[英]Invoke from background thread in layered application
Windows形成應用程序,在單獨的線程中進行繁重的處理。 在處理過程的某個地方,我需要從用戶那里獲得一些反饋(例如問一些有關向另一台設備的視覺輸出的問題)。 如果要在UI層中執行此操作,我將非常樂於使用控件的Invoke
並執行此操作。 處理在業務層中完成。 我問業務層中的每個人,沒人知道諸如Control
, Invoke
, MainForm
等這樣的關鍵字。我如何通知Main表單並獲取輸入? (事件?還是我缺少一些簡單的東西?)
您需要讓您的請求從業務層向上傳播,然后從您的UI的表示層調用它。
正如您在注釋中所建議的,執行此操作的一種方法是使用從業務層觸發並由表示層處理的事件,但這取決於您是否希望構建應用程序以在各層之間進行通信使用事件。
我個人的喜好是讓各層直接直接進行通信,因此在這種情況下,我將讓業務層與表示輸入的表示層進行通信,然后表示層會將請求編組到視圖(UI )通過Invoke
本身。
一種方法是在您的業務層中創建一個事件 ,您可以通過該事件從您的控件/表單代碼進行連接。 當您的控件/窗體接收到該事件時,請編組回到調用Invoke / BeginInvoke的UI線程上,以便相應地更新您的控件。
例如,在您的模型代碼中:
public class ModelFoo
{
public event EventHandler SomethingInterestingHappened;
...
調用(或廣播)事件時,通常的做法是通過“ On”方法執行此操作( 使調用成為線程安全的 -另請參見this ):
private void
OnSomethingInterestingHappened
()
{
var SomethingInterestingHappenedCopy = SomethingInterestingHappened;
if (SomethingInterestingHappenedCopy != null)
{
// TODO add your event data in the second args here
SomethingInterestingHappenedCopy (this, EventArgs.Empty);
}
}
然后從您的UI線程訂閱它,例如:
ModelFoo.SomethingInterestingHappened += SomethingInterestingHappenedHandler;
哪里:
private void SomethingInterestingHappenedHandler(object sender, EventArgs e)
{
// You can call if(this.InvokeRequired) here, since
// you might already be on the UI thread.
// However from other threads call Invoke/BeginInvoke if wanting
// to process synchronously/asynchronously depending on what you need and
// you need to update a control object.
Invoke(new MethodInvoker(delegate
{...
我發現事件非常有用,因為感覺就像您將UI與模型很好地分離了一樣 。 這些事件也可以在接口上定義,因此UI代碼可以與抽象事物進行對話,這意味着您可以在需要時更改基礎類型(例如,進行測試)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.