Domanda

passando due parametri per un nuovo thread sul ThreadPool a volte può essere complicato, ma sembra che con le espressioni lambda e metodi anonimi, posso fare questo:

public class TestClass
{
    public void DoWork(string s1, string s2)
    {
        Console.WriteLine(s1);
        Console.WriteLine(s2);
    }
}

try
{
    TestClass test = new TestClass();
    string s1 = "Hello";
    string s2 = "World";
    ThreadPool.QueueUserWorkItem(
        o => test.DoWork(s1, s2)
        );
}
catch (Exception ex)
{
    //exception logic
}

Ora, ho certamente semplificato questo esempio, ma questi punti sono chiave:

  • Gli oggetti stringa trasmesse, sono immutabili e quindi threadsafe
  • Le variabili S1 e S2 sono dichiarati nell'ambito di applicazione del blocco try, che esco subito dopo l'accodamento dei lavori al pool di thread, quindi le variabili S1 e S2 non sono mai modificato dopo che.

C'è qualcosa di sbagliato in questo?

L'alternativa è quella di creare una nuova classe che implementa un tipo immutabile, con 3 membri: prova, s1, s2 e. Questo sembra proprio come lavoro extra senza alcun beneficio a questo punto.

È stato utile?

Soluzione

Non c'è niente di sbagliato in questo. Il compilatore è essenzialmente facendo automaticamente quello che hai descritto come alternativa. Si crea una classe per contenere le variabili acquisite (prova, S1 e S2) e passa un'istanza delegato al lambda che viene trasformato in un metodo sulla classe anonima. In altre parole, se si è andato avanti con la vostra alternativa si finirebbe con soemthing molto simile a quello che il compilatore appena generato per te.

Altri suggerimenti

Per questo particolare esempio, non v'è nulla di sbagliato qui. Lo stato di aver superato in altro thread è wholely contenuta e nessuno dei tipi di coinvolgere avere problemi filo di affinità.

E 'un bel modo di farlo. Non vedo alcun svantaggi di usare lambda. E 'semplice e pulito.

Quello che state osservando è riferito come una chiusura. Come chuckj stati , il compilatore sta generando una classe in fase di compilazione che corrisponde ai membri che sono accessibili all'esterno della chiusura.

L'unica cosa che si deve preoccupare è se si dispone di rif o parametri fuori. Mentre le stringhe sono immutabili, i riferimenti a loro (o qualsiasi variabile) non sono.

Un problema potenziale con il pattern è che è molto allettante per espanderlo in qualcosa di più generico, ma meno sicuri come questo (zero code-non aspettatevi di lavorare):

public static void QueueTwoParameterWorkItem<T1, T2>(T1 value1, T2 value2, workDelegate<T1,T2> work)
{
    try
    {
        T1 param1 = value1;
        T2 param2 = value2;
        ThreadPool.QueueUserWorkItem(
            (o) =>
            {
                work(param1, param2);
            });
    }
    catch (Exception ex)
    {
        //exception logic
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top