簡體   English   中英

使用WinForms GUI Control進行線程安全事件

[英]Thread safe events with WinForms GUI Control

我知道GUI組件不能在不同的線程中使用。 所以你通常做一個檢查InvokeRequired的方法,然后調用Invoke等。但這是很多代碼。 有沒有辦法做這樣的事情: MyEvent += myDelegate ,這個myDelegate將從分配它的線程執行? 為什么Invoke方法只能從Control類中獲得? 我唯一的想法就是制作自己的方法,如AddDelegate(委托..,控制c)或類似的東西。

知道怎么做到這一點?

為了避免這種重復代碼,我通常創建一個類來隔離這個邏輯。 當應用程序啟動時,我會初始化此類並在整個應用程序中使用它。 優點是它可以在控件之外使用。

public static class UI
{
    private static Control internalControl;

    public static void Initialize(Control control)
    {
        internalControl = control;
    }

    public static void Invoke(Action action)
    {
        if (internalControl.InvokeRequired)
        {
            internalControl.Invoke(action);
        }
        else
        {
            action();
        }
    }
}

初始化主窗體時初始化:

UI.Initialize(this);

用法:

UI.Invoke(() => { this.Text = "Test"; });

我用了一個相當簡單的方法:

private void execThreadSafeMethod(Control ctrl)
{
     MethodInvoker method = (MethodInvoker) delegate
     {
         //Do something that you always wanted to do :)
     }
     if(ctrl.InvokeRequired == true)
     {
          ctrl.Invoke(method);
     }
     {
          method.Invoke();
     }
}

你在使用.Net 4嗎? 如果是這樣,您可以使用異步任務。

您將從創建控件的主線程的同步上下文創建TaskScheduler。

var uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();

然后,您可以在后台線程上運行的任何方法中使用它來更新主線程上的任何控件。

Task.Factory.StartNew(
    () => { MessageBox.Show("Message from separate thread.") }, 
    CancellationToken.None, 
    TaskCreationOptions.None, 
    uiTaskScheduler);

保持等待找到我的方法,但我沒有看到它(希望我看到正確的問題)

這是我在單獨的線程中處理Invokes的方法:

this.Invoke((MethodInvoker)delegate() { /*whatever I need done*/ });

這很好,因為您可以將代碼保存在適用的位置,而不是跳轉

this.Invoke((MethodInvoker)delegate() {
    //here is some code I need to run on the main thread
    //usually making a label visible or some other bs
    //might want to resize my form or update a list box, who knows
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM