Discussioni ed espressioni lambda
-
20-08-2019 - |
Domanda
Qual è la differenza tra i due pezzi di codice qui sotto? Ci saranno problemi con il secondo?
Scenario 1:
private void Log(Exception e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Log), e);
}
private void Log(object obj)
{
Exception e = (Exception)obj;
Logger.Log(e);
}
Scenario 2
private void Log(Exception e)
{
ThreadPool.QueueUserWorkItem(
(obj) =>
{
Logger.Log(e);
});
}
Nello scenario 2, non sto passando l'eccezione come parametro al ThreadPool. Come si verifica il marshalling dei thread dell'oggetto eccezione? Ci saranno problemi? Quali sono i limiti nel fare questo? Il grande vantaggio è che puoi passare qualsiasi numero di parametri molto facilmente.
Soluzione
L'unica differenza è che nello scenario due si sta chiudendo la variabile e
che sposta effettivamente la variabile di stack e
in un tipo personalizzato che viene spostato nell'heap non lo perdi.
Penso che dovrebbe funzionare bene.
Modifica: Per quanto riguarda le prestazioni, non dovrebbe esserci una differenza significativa tra i due scenari. Nello scenario 1 si sta già passando l'eccezione come state
al metodo QueueUserWorkItem
che sposta internamente tale riferimento di eccezione sull'heap. L'unico sovraccarico è che quando si utilizza una chiusura è che il compilatore crea un tipo per te e memorizza tutte le variabili acquisite come campi su quel tipo.
Altri suggerimenti
Solo per notare, invece della Lambda, potresti fare lo stesso con un metodo anonimo e funzionerebbe anche in C # 2.0:
ThreadPool.QueueUserWorkItem(delegate(Object e)
{
Logger.Log(e as Exception);
});