2010-11-14 67 views
13

我目前正在C#中使用一個項目。我有一個叫做updateProgress()的方法,它有兩個int參數(count和totalRows)。在c中使用線程中的參數運行方法#

如果我說updateProgress(count,totalRows)這個方法可以正常工作,但我想在新線程中運行此方法。

我該怎麼去做這件事,我已經在網上看,一切都看起來過於複雜,我想做的事情。

感謝這個

+2

不要從工作線程更新UI。 – 2010-11-14 19:28:42

回答

22

事情是這樣的你有所幫助:

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

感謝大家的幫助 – Boardy 2010-11-14 21:05:51

+0

嘗試'線程t =新線程(new ParameterizedThreadStart(method)); t.Start(參數);'但那不起作用。儘管你在這裏做了一些片段。謝謝 – Ortund 2017-08-04 11:26:13

+0

@Outund'method'是否有'void method(object)'簽名,或者是其他類型的參數? – cdhowie 2017-08-04 13:05:16

0

這裏是不匿名委託一個更復雜的例子。查看已完成功能的結果。

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

「......沒有代表」是什麼意思?我在代碼中看到了幾個隱式方法組轉換。 – Ani 2010-11-14 17:59:20

+0

它使用函數而不是內聯代理。有時他們更容易與新手線程用戶一起工作和閱讀。 – rboarman 2010-11-14 18:00:57

+0

然後我想你應該說「沒有*匿名*代表」。否則,例如,OP可能完全錯過了正在創建'ProgressChangedEventHandler'委託實例的事實。 – Ani 2010-11-14 18:02:10

5

要知道,其實線程是一個相當複雜的問題,所以如果你有麻煩理解在.NET Framework提供了異步的API,我懷疑你應該開始首先使用線程。

無論如何,你有幾種選擇:

  • 分拆線程由你自己(像cdhowie指出的),這是相當氣餒。

  • 如果您在.NET 4上運行,則使用TPL(任務並行庫)。Here是一個很好的介紹。 TaskFactory.StartNew(() => updateProgress(count, totalRows));

  • 如果您在舊版本的.NET上運行,請使用ThreadPool。 ThreadPool.QueueUserWorkItem(s => updateProgress(count, totalRows));

當然還有其他的方法也一樣,但是這是海事組織最重要的。

最好的問候,
奧利弗Hanappi

0

嘗試以下

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

有不同的方式在不同的線程上運行的方法,像ThreadBackgroundWorkerThreadPoolTask。選擇哪一個取決於各種事情。

從該方法的名稱看,這聽起來像該方法應該在應用程序的GUI中顯示一些進度。如果是這樣的話,你的必須在GUI線程上運行該方法。如果你想從另一個線程調用它,你必須在WinForms中使用WPF中的Dispatcher.Invoke()Control.Invoke()

1

這已經差不多一年了,我的回答將不會添加任何東西「新」已經在其他答案已經說過。

如果有人正在使用.Net 4。0或更高,最好的選擇是使用任務,並讓框架決定最好的,通過調用TaskFactory.StartNew(...)。對於舊版本,仍然最好使用ThreadPool.QueueUserWorkItem(...)來利用線程池。

現在,如果仍然有人想使用線程的基本方法(創建新的線程)由於某種原因,那麼這

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

可以寫在一個小更清潔的方式,使用lambda表達式,像這樣

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