2012-04-19 86 views
1

我正在一個應用程序中,當我點擊一個按鈕,我要開始新的形式,並在同一時間創建的谷歌文檔的新文檔的一些原因。 我已經成功實現了上述功能,但是當應用程序忙於在Google文檔中創建新文檔時,新加載的表單的UI會凍結。 我在某處讀到,如果使用多線程,可以避免這種情況。 所以現在我想問我應該創建兩個線程,在其中一個我應該放置代碼來創建新的窗體,另一個我應該放置代碼來創建一個文檔在谷歌文檔。 或者我應該創建一個線程,在這個線程中我應該放置代碼來創建新的Google文檔,並讓新的表單創建代碼在主進程中? 另外什麼是在一個已經寫好的代碼中實現線程的最簡單的方法?如有可能,請提供一些參考閱讀材料。需要幫助實現多線程在C#中

+1

您的第一選擇應該是與Google會談的[Backgroundworker](http://msdn.microsoft.com/en-us/library/cc221403%28VS.95%29.aspx)。 – 2012-04-19 08:15:05

+0

@HenkHolterman - 我會去那。只需在新窗體上放置一個代碼,並將所有代碼放在那裏。它可以在新窗體初始化時運行。任務完成。 – 2012-04-19 08:37:06

回答

0

恕我直言。你應該只創建一個線程,你可以創建谷歌文檔(所以你會有兩個線程)。

+0

如果你想創建線程的代碼在哪裏將創建谷歌文檔,我需要你的函數屬性(返回值,params) – Likurg 2012-04-19 08:20:27

2

你可以使用一些技巧做你問什麼,但我會建議任務並行庫(TPL)(或BackgroundWorker)這一點。

創建/啓動新的形式具有非常小的開銷(在大多數情況下),所以在我看來,你應該啓動UI線程上的形式,並在後臺線程創建谷歌文檔。因此,使用TPL,你會碰到這樣的(非常簡單的例子)

// In click event. 
MyForm newForm = new MyForm(); 
newForm.Show(); 

Task googleDocTask = Task.Factory.StartNew(() => 
{ 
    // Do your stuff with Google Docs. 
    // Note you cannot access the UI thread from within this delegate. 
}); 

對於穿線在C大討論#看到Joseph Albahari's page on threading

欲瞭解更多信息和比較完整地介紹了TPL看到here

我希望這會有所幫助。

0

最簡單的方法是使用BackgroundWorker或使用ThreadPool。如果您的主UI不關心其他任務何時完成,則線程池更簡單。

2

只需創建一個線程。我建議使用BackgroundWorker。他們非常簡單。

拋出這個在您的類的頂部:

private BackgroundWorker googleDocWorker = new BackgroundWorker(); 

在構造函數將這個:

googleDocWorker.DoWork += new DoWorkEventHandler(googleDocWorker_DoWork); 
googleDocWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(googleDocWorker_RunWorkerCompleted); 

把這些方法在你的類:

void googleDocWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    // You can use this to alert you that the google doc is created. 
} 

void googleDocWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    // Create google doc here. 
} 

調用此開始創建谷歌文檔:

googleDocWorker.RunWorkerAsync(); 

現在,如果你需要一些數據傳遞到BackgroundWorker的,你可以在你想真的什麼通過。你可以通過使用一個對象數組來傳入一個字符串,甚至可以傳入多個不同類型的對象。這裏有一個例子在多個對象發送:

googleDocWorker.RunWorkerAsync(new object[] { "doc name", contents }); 

現在,這意味着他們將不得不在_DoWork方法進行處理:

void googleDocWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    // Create google doc here. 
    object[] args = (object[])e.Argument; 
    String docName = (string)args[0]; 
    SomeClass contents = (SomeClass)args[1]; 
} 

比方說,在創建文檔後,你想回送的URL,這是剛剛創建的文檔,你只傳遞迴_RunWorkerCompleted方法從_DoWork方法:

void googleDocWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    // Create google doc here. 

    ... 

    e.Result = myURL; 
} 

獲取網址,一旦你在RunWorkerComplete是d方法,它幾乎與DoWork方法相同。

void googleDocWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    // You can use this to alert you that the google doc is created. 
    String docURL = (String)e.Result; 
} 

希望有幫助! (:

6

你確實有很多選擇

(1)BackgroundWorker的如果你真的想在WinForms的異步工作的最簡單的編程模型,這將是這個它通常用來做一些。異步任務和報告進度,但是如果你不需要,你不必報告進度。

(2)基於事件的異步模式如果你想做一個完整的組件,異步任務,完全控制報告進度和您自己的自定義事件,那麼這是一種方法他還可以幫助您理解線程而不是BackgroundWorker。因爲我是一個視覺的人,I created a full video presentation on how to do just this with WinForms

(3)任務並行庫。你可以使用WinForms的TPL,並且我寫了一個very detailed blog post on how to do just that here

(4)異步和等待。請注意,這需要僅包含在Visual Studio 11中的.NET 4.5,C#5.0和C#5.0編譯器,Visual Studio 11現在只能在BETA中使用。 However, I also have a full blog post on how to do just this

(5)ISynchronizedInvoke with Threads。這是另一個選項,其中I also have a full blog about

這真的取決於你選擇哪種方法。我的建議是對每種方法進行簡要介紹,然後根據主體對您的感受程度來選擇一種方法,或者採用哪種方法可以最好地滿足您的要求。