2011-04-05 54 views
0

對於C#和編碼來說,這是一個相對較新的概念。我正在嘗試編寫一個具有某些邏輯的程序,並且還指出了進度條的進度。我正在Main()中啓動一個線程,它執行我所有的業務邏輯。它有一些事件在我需要進度條的地方被激怒。C#Winform多線程序列

Form對象訂閱業務邏輯事件並具有線程安全委託,它們被調用以更新進度條和文本標籤。

我的問題是,因爲Form是在主線程中啓動的,所以我必須在Application.Run()之前啓動業務邏輯線程。當第一個ProgressUpdate事件被激怒時,Form對象仍然不存在。我想一個hacky的方法是在第二個線程中添加Thread.Sleep(100),但我不喜歡這樣。我如何解決這個問題?我在完全錯誤的軌道上? (我是否有道理?)

 Form1 theForm = new Form1(); 
     CreateReport theCreateReport = new CreateReport(); 
     Thread t = new Thread(new ThreadStart(theCreateReport.DoProcess)); 
     t.IsBackground = true; 
     theForm.Subscribe(theCreateReport); 
     t.Start(); 
     Application.Run(theForm); 

theForm是表單。創建報告是我的業務邏輯開始的地方。

回答

0

在調用構造函數(在第一行)之後,窗體已經存在 - 它只是不可見。所以你不用擔心,當你開始新線程時,所有的東西都會被初始化。

+0

這就是爲什麼我將構造函數從默認的VC#S項目中分離出來的原因。它似乎並沒有工作。給我一個錯誤,說在創建對象之前我不應該使用Invoke/BeginInvoke。如果我將一個try catch塊放入空捕捉塊中,它確實有效,但感覺像是一個黑客。這可能只是我很挑剔。 – whatsinaname 2011-04-06 00:10:56

+0

這是一個黑客。 .Net中基於表單的應用程序基本上是圍繞主表單的概念構建的。沒有理由與之抗衡,因爲您的項目已經使用了主表單。 – MusiGenesis 2011-04-06 00:27:59

+0

將此標記爲答案,因爲正如波馬提到的那樣,表單已經存在。該錯誤在我的代碼的不同部分。謝謝。 – whatsinaname 2011-04-18 14:03:14

1

也許你應該在OnLoad事件中啓動你的業務邏輯?

4

要使用一個或多個BackgroundWorker對象而不是業務邏輯線程。這將爲您管理線程,併爲您提供向主線程提供進度反饋的方法。

+0

與從Form1()方法中啓動我的線程有什麼不同?我已經有我的處理人員和代表。從Form中開始/執行所有業務邏輯是否是一種很好的編程實踐?就像我剛纔提到的那樣,這裏是一個完整的新手。謝謝。 – whatsinaname 2011-04-06 00:08:26

+0

如果你已經有一些工作,然後通過一切手段使用它。 BackgroundWorker只是爲您提供一種簡單的方法,將離散任務拋出到另一個線程,並在稍後獲得結果,而無需管理自己的線程。 – geofftnz 2011-04-06 01:39:03

0

Main,只需創建表格和Application.Run它。在表單的Load事件中,啓動您的線程。

你不會像現在那樣做事情而獲得任何優勢。正如你已經發現的那樣,它會造成時序/序列問題。

解決問題的最佳方法是不要讓他們擺在首位。

+0

我被告知完全分離GUI和業務邏輯是一種很好的做法。 (而不是從GUI方法中啓動業務邏輯線程)。但是,這確實來自我與之合作的Java開發人員。所以我不知道它是否適用於C#編碼的情況。 – whatsinaname 2011-04-06 00:03:53

+0

GUI和業務邏輯的分離與代碼的組織方式有關,而不是運行不同對象的線程。一般來說,多線程應用程序的可靠性低於單線程應用程序,因爲通過代碼的路徑受到線程調度程序的控制,因此難以預測。有合理的理由需要多線程的固有風險(如果你知道自己在做什麼,它就可能安全地做到這一點),但符合三層正統的標準確實不是其中之一。 – MusiGenesis 2011-04-06 00:21:38

0

我會使用BackgroundWorker,你仍然可以使用它的事件和委託。這一次你將會結束並解僱Background Worker的「ProgressChanged」和「RunWorkerCompleted」事件。

而你表單可以監聽這些事件並相應地更新ProgressBar。

BWorker更好地處理切換到GUI線程和異常處理。

您可以在Form Load上初始化BackgroundWorker。