通过在线程库中处理来删除对Invoke()的需求

时间:2010-01-22 13:22:28

标签: c# wpf winforms multithreading

在我正在编写的类库中,我有一个方法允许库在不同的线程上执行某些操作,这类似于:

    public void DoStuffAsync(AP p)
    {
        this.Running = true;
        this.Cancel = false;

        ParameterizedThreadStart threadStart = new ParameterizedThreadStart(DoStuff);
        Thread procThread = new Thread(threadStart);
        procThread.Start(p);
    }

我还在开发人员可以挂接的接口上声明了许多事件,例如StatusUpdate和ProgressUpdate。我目前正在编写一个小测试应用程序(目前在WPF中,虽然我希望在WinForms中有相同的行为)调用DoStuffAsync(),然后更新进度条和标签。

不幸的是,第一遍我得到了一个错误,通常的线程不是拥有控件的那个。我想要做的是删除用户在UI端调用Invoke()的需要,并让他们只需订阅事件并让它们工作。

所以问题是,在处理事件处理程序时,有什么方法可以做到这一点是我的代码?目前触发如下:

        public void UpdateProgress(object sender, ProgressEventArgs e)
        {
            if (handler != null)
            {
                handler(sender, e);
            }
        }

2 个答案:

答案 0 :(得分:3)

您将需要对客户端的Dispatcher对象的引用,以便您可以调用Dispatcher.Invoke或Dispatcher.BeginInvoke来封送对客户端UI线程的调用。这样做是让客户通过构造函数或属性为您提供引用。

另一种方法是在类构造函数中存储对SynchronizationContext.Current的引用。使用其Send或Post方法。然而,这需要客户端正确初始化WPF(必须已调用Application.Run)并从其UI线程构造您的类对象。

答案 1 :(得分:3)

改为使用AsyncOperationManager

它会为你做调用。 (在内部它使用SynchronizationContext,如nobugz所描述的)