首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >WPF Dispatcher.BeginInvoke和UI/背景线程

WPF Dispatcher.BeginInvoke和UI/背景线程
EN

Stack Overflow用户
提问于 2009-07-30 16:44:32
回答 5查看 72.8K关注 0票数 18

我想我需要澄清一下WPF、Dispatcher.Invoke和Dispatcher.BeginInvoke的用法。

假设我有一些长时间运行的'work‘代码,比如在一个简单的WPF应用程序中按下一个按钮就可以调用它:

代码语言:javascript
复制
longWorkTextBox.Text = "Ready For Work!";
Action workAction = delegate
    {
    Console.WriteLine("Starting Work Action");
    int i = int.MaxValue;
    while (i > 0)
        i--;
    Console.WriteLine("Ending Work Action");
    longWorkTextBox.Text = "Work Complete";
    };
longWorkTextBox.Dispatcher.BeginInvoke(DispatcherPriority.Background, workAction);

这段代码在执行workAction时锁定了我的用户界面。这是因为Dispatcher调用总是在UI线程上运行,对吧?

假设这样,那么配置我的dispatcher以在独立于我的UI的线程中执行 workAction 的最佳实践是什么?我知道我可以向我的workAction添加一个BackgroundWorker,以防止我的UI锁定:

代码语言:javascript
复制
longWorkTextBox.Text = "Ready For Work!";
Action workAction = delegate
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += delegate
    {
        Console.WriteLine("Starting Slow Work");
        int i = int.MaxValue;
        while (i > 0)
        i--;
        Console.WriteLine("Ending Work Action");
    };
    worker.RunWorkerCompleted += delegate
    {
        longWorkTextBox.Text = "Work Complete";
    };
    worker.RunWorkerAsync();
 };
 longWorkTextBox.Dispatcher.BeginInvoke(DispatcherPriority.Background, workAction);

除了使用BackgroundWorker之外,还有没有更优雅的方法来完成这项工作呢?我总是听说BackgroundWorker很古怪,所以我很好奇有没有其他的选择。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-07-30 17:05:11

老实说,我认为BackgroundWorker是这方面最优雅的解决方案。我想不出比这更简单的方法了。

票数 25
EN

Stack Overflow用户

发布于 2009-07-30 22:01:00

真的,查利的答案就是你想要的。

但是,如果可能的话,您可能会考虑是否可以打包您的工作,以便单个工作单元较小,并且不会对UI产生太大影响。这将允许您直接使用Dispatcher。WPF线程化页面上有一个很好的例子:https://msdn.microsoft.com/en-us/library/ms741870%28v=vs.100%29.aspx

票数 4
EN

Stack Overflow用户

发布于 2012-05-30 13:52:26

我也不喜欢BackgroundWorker。一个简单的替代方案可以是这样的:

代码语言:javascript
复制
using System;
using System.Threading;
using System.Windows;

namespace Sample
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        protected override void OnSourceInitialized(EventArgs e)
        {
             base.OnSourceInitialized(e);
             longWorkTextBox.Text = "Ready For Work!";
       }

        private void startButton_Click(object sender, RoutedEventArgs e)
        {
            new Thread(Work).Start();
        }

        void Work()
        {
            longWorkTextBox.Dispatcher.BeginInvoke((Action)(() => { longWorkTextBox.Text = "Working..."; }));
            Console.WriteLine("Starting Work Action");
            int i = int.MaxValue;
            while (i > 0)
                i--;
            Console.WriteLine("Ending Work Action");
            longWorkTextBox.Dispatcher.BeginInvoke((Action)(() => { longWorkTextBox.Text = "Work Complete"; }));
        }
    }
}

很简单,不是吗?

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1207832

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档