2010-11-14 13 views
13

Attualmente sto lavorando a un progetto in C#. Ho un metodo chiamato updateProgress() che ha due parametri int (count e totalRows).Esecuzione di un metodo con parametri in una discussione in C#

Se ho chiamato il metodo dicendo updateProgress (count, totalRows) questo funziona bene ma voglio eseguire questo metodo all'interno di una nuova discussione.

Come posso fare questo, ho cercato online e tutto sembra troppo complicato per quello che voglio fare.

Grazie per il vostro aiuto con questo

+2

Non aggiornare l'interfaccia utente da un thread di lavoro. –

risposta

22

qualcosa di simile:

new Thread(delegate() { 
    updateProgress(count, totalRows); 
}).Start(); 
+0

Grazie a tutti per il vostro aiuto – Boardy

+0

Provato 'Thread t = new Thread (new ParameterizedThreadStart (metodo)); t.Start (parametro); 'ma non ha funzionato. Il tuo frammento qui però è stato fatto. Grazie – Ortund

+0

@Ortund 'metodo' ha la firma' metodo void (oggetto) ', o è il parametro di qualche altro tipo? – cdhowie

0

Ecco un esempio più complesso, senza delegati anonimi. Guarda il risultato nella funzione completata.

using System; 
using System.Threading; 
using System.ComponentModel; 

class Program 
{ 
    static BackgroundWorker _bw; 

    static void Main() 
    { 
    _bw = new BackgroundWorker 
    { 
     WorkerReportsProgress = true, 
     WorkerSupportsCancellation = true 
    }; 
    _bw.DoWork += bw_DoWork; 
    _bw.ProgressChanged += bw_ProgressChanged; 
    _bw.RunWorkerCompleted += bw_RunWorkerCompleted; 

    _bw.RunWorkerAsync ("Hello to worker"); 

    Console.WriteLine ("Press Enter in the next 5 seconds to cancel"); 
    Console.ReadLine(); 
    if (_bw.IsBusy) _bw.CancelAsync(); 
    Console.ReadLine(); 
    } 

    static void bw_DoWork (object sender, DoWorkEventArgs e) 
    { 
    for (int i = 0; i <= 100; i += 20) 
    { 
     if (_bw.CancellationPending) { e.Cancel = true; return; } 
     _bw.ReportProgress (i); 
     Thread.Sleep (1000);  // Just for the demo... don't go sleeping 
    }       // for real in pooled threads! 

    e.Result = 123; // This gets passed to RunWorkerCompleted 
    } 

    static void bw_RunWorkerCompleted (object sender, 
            RunWorkerCompletedEventArgs e) 
    { 
    if (e.Cancelled) 
     Console.WriteLine ("You canceled!"); 
    else if (e.Error != null) 
     Console.WriteLine ("Worker exception: " + e.Error.ToString()); 
    else 
     Console.WriteLine ("Complete: " + e.Result);  // from DoWork 
    } 

    static void bw_ProgressChanged (object sender, 
            ProgressChangedEventArgs e) 
    { 
    Console.WriteLine ("Reached " + e.ProgressPercentage + "%"); 
    } 
} 
+0

Cosa intendi con "... senza delegati"? Vedo diverse conversioni di gruppo metodo implicite nel codice. – Ani

+0

Utilizza funzioni anziché delegati in linea. A volte sono più facili da utilizzare e leggere in particolare per gli utenti di thread principianti. – rboarman

+0

Quindi penso che dovresti chiarire dicendo "senza delegati * anonimi". Altrimenti, l'OP potrebbe perdere completamente il fatto che sia stata creata un'istanza delegata 'ProgressChangedEventHandler', ad esempio. – Ani

5

essere consapevoli del fatto che la filettatura in realtà è piuttosto un argomento complesso, quindi se avete problemi di comprensione le API asincroni disponibili in .NET Framework, dubito che si dovrebbe iniziare a utilizzare le discussioni, in primo luogo.

In ogni caso, sono disponibili diverse opzioni:

  • Spin off un filo da soli (come cdhowie ha sottolineato), che è piuttosto scoraggiato.

  • Utilizzare il TPL (libreria parallela delle attività) se si utilizza .NET 4. Here è una buona introduzione. TaskFactory.StartNew(() => updateProgress(count, totalRows));

  • Utilizzare il ThreadPool se si utilizza una versione precedente di .NET. ThreadPool.QueueUserWorkItem(s => updateProgress(count, totalRows));

Naturalmente ci sono altri modi, ma questo sono imo i più importanti.

migliori saluti,
Oliver Hanappi

0

prova a seguire

ThreadPool.QueueUserWorkItem((o) => { updateProgress(5, 6); }); 
1

Ci sono diversi modi per eseguire un metodo in un thread diverso, come Thread, BackgroundWorker, ThreadPool o Task. Quale scegliere dipende da varie cose.

Dal nome del metodo, sembra che il metodo mostri alcuni progressi nella GUI dell'applicazione. Se questo è il caso, è necessario eseguire il metodo sul thread GUI. Se si desidera chiamarlo da un altro thread, è necessario utilizzare Dispatcher.Invoke() in WPF e Control.Invoke() in WinForms.

1

Questo è stato quasi un anno e la mia risposta non aggiungerà nulla "nuovo" a ciò che è già stato detto in altre risposte.

Se qualcuno sta usando .Net 4.0 o superiore, le migliori opzioni sarebbero quelle di utilizzare un'attività e lasciare che il framework decida il meglio, chiamando TaskFactory.StartNew(...). Per le versioni precedenti, è ancora meglio utilizzare il pool di thread utilizzando ThreadPool.QueueUserWorkItem(...).

Ora, se ancora qualcuno vuole usare il filo in modo di base (creare nuovo thread) per qualche ragione, allora questo

new Thread(delegate() { 
    updateProgress(count, totalRows); 
}).Start(); 

possono essere scritti in un modo più pulito po ', utilizzando l'espressione lambda, In questo modo

new Thread(() => updateProgress(count, totalRows)).Start(); 
Problemi correlati