c# - BackgroundWorker 进程需要引发要在主 (UI) 线程上处理的自定义事件

标签 c# wpf backgroundworker synchronizationcontext

我有一个用于大型 CSV 文件的解析器类。 parse 方法逐行读取大文件的工作是在 backgroundWorker 中完成的。使用 backgroundWorker.ReportProgress 将完成百分比信息传递给 UI 线程。方法,这样我的表单上的进度条就可以完成它的工作。这工作正常。

但是,我还想引发一个自定义事件,该事件将从 CSV 文件的第一行获取的字段名列表发送回 UI (WPF),以便可以将它们放置在下拉列表中。如果解析器遇到格式错误的行或其他障碍,我还想通过事件通知用户。

我在后台执行的解析器进程可以简单地引发一个事件吗?或者必须将 SynchronizationContext.Current 从主 UI 线程传递到我的解析器类,然后它会使用 Post 方法?

最佳答案

如果您绝对必须从您的 DoWork 中安排 UI 线程上的工作。处理程序,最简单的方法是使用 Dispatcher.Invoke :

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();

        var worker = new BackgroundWorker();

        worker.DoWork += (s, e) =>
        {
            // Suppose we've done some processing and need to notify the UI.
            // We're on the background thread, so we can't manipulate the UI directly.
            this.Dispatcher.Invoke(new Action(() =>
            {
                // This will actually run on the UI thread.
                this.Label.Content = "hello from the background thread.";
            }));
        };

        worker.RunWorkerAsync();
    }
}

关于事件及其执行线程同步的神奇能力似乎有很多困惑,所以请允许我咆哮一下。

事件是美化的多播代表。当您引发一个事件时,其调用列表中的每个委托(delegate)都会在引发该事件的线程上被调用。因此,如果您在自定义解析器类中创建一个事件只是为了让它从 DoWork处理程序,事件处理程序仍将在后台线程上执行,您仍然需要找到一种方法来切换到 UI 同步上下文 - 要么通过执行一些 Invoke/SynchronizationContext.Post/Send新事件的处理程序中的魔法,或者通过调用/发布/发送实际的事件引发逻辑。

开箱即用事件处理程序的原因,例如 RunWorkerCompletedProgressChanged在 UI 线程上运行的是,这些事件实际上是由 BackgroundWorker 在 UI 线程上引发的。为了您的方便。是的,您可以通过捕获 SynchronizationContext 来产生类似的行为。然后将自定义解析器类中的事件引发逻辑发布/发送给它。或者,如果您选择在后台线程上引发事件,您可以随时使用 Dispatcher.Invoke在 WPF 组件的处理程序中。

关于c# - BackgroundWorker 进程需要引发要在主 (UI) 线程上处理的自定义事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16879095/

相关文章:

c# - 接口(interface)向下转换

WPF:自定义窗口

WPF:缩放用户控件动画

c# - volatile 变量的值在多线程中不改变

python - GAE中的后台进程

c# - RectForMapRect MonoTouch.UIKit.UIKitThreadAccessException

c# - 在 gridview 中分页时试图了解错误的来源

c# - 是否可以在 C# 中使用作为关键字的值定义枚举?

c# - WPF RichTextBox 滚动到 TextPointer

python - RQ - 导入错误 : No module named XXX