C# 如何使用WPF后台工作程序

C# 如何使用WPF后台工作程序,c#,wpf,multithreading,backgroundworker,C#,Wpf,Multithreading,Backgroundworker,在我的应用程序中,我需要执行一系列初始化步骤,这些步骤需要7-8秒才能完成,在此期间,我的UI变得无响应。要解决此问题,我将在单独的线程中执行初始化: public void Initialization() { Thread initThread = new Thread(new ThreadStart(InitializationThread)); initThread.Start(); } public void InitializationThread() {

在我的应用程序中,我需要执行一系列初始化步骤,这些步骤需要7-8秒才能完成,在此期间,我的UI变得无响应。要解决此问题,我将在单独的线程中执行初始化:

public void Initialization()
{
    Thread initThread = new Thread(new ThreadStart(InitializationThread));
    initThread.Start();
}

public void InitializationThread()
{
    outputMessage("Initializing...");
    //DO INITIALIZATION
    outputMessage("Initialization Complete");
}
我读过几篇关于
BackgroundWorker
的文章,以及它应该如何让我的应用程序保持响应,而不必编写线程来执行冗长的任务,但我在尝试实现它时没有取得任何成功,有人能告诉我如何使用
BackgroundWorker

  • 添加使用
  • 宣布:
  • 订阅活动:
  • 实施两种方法:
  • 根据需要随时运行worker async
  • 跟踪进度(可选,但通常很有用)

    a) 订阅
    ProgressChanged
    事件并在
    DoWork

    b) 设置worker.WorkerReportsProgress=true(计入@zagy)

  • 我发现这个()包含了@Andrew答案中缺少的其他细节

    我发现非常有用的一件事是工作线程无法访问主窗口的控件(在它自己的方法中),但是当在主窗口事件处理程序中使用委托时,这是可能的

    worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
    {
        pd.Close();
        // Get a result from the asynchronous worker
        T t = (t)args.Result
        this.ExampleControl.Text = t.BlaBla;
    };
    

    您可能还需要考虑使用
    任务
    而不是后台工作人员

    在您的示例中,最简单的方法是
    Task.Run(InitializationThread)

    使用任务而不是后台工作人员有几个好处。例如,.NET4.5中新的async/await特性使用
    Task
    进行线程处理。下面是一些关于
    任务的文档

    使用系统;
    使用系统组件模型;
    使用系统线程;
    命名空间BackGroundWorkerExample
    {   
    班级计划
    {  
    私有静态后台工作程序后台工作程序;
    静态void Main(字符串[]参数)
    {  
    backgroundWorker=新的backgroundWorker
    {  
    WorkerReportsProgress=true,
    WorkerSupportsScanCellation=真
    };  
    backgroundWorker.DoWork+=backgroundWorker\u DoWork;
    //用于将操作进度显示到UI。
    backgroundWorker.ProgressChanged+=backgroundWorker\u ProgressChanged;
    //手术结束后。
    backgroundWorker.RunWorkerCompleted+=backgroundWorker\u RunWorkerCompleted;
    backgroundWorker.RunWorkerAsync(“在接下来的5秒内按Enter键取消操作:”;
    Console.ReadLine();
    if(backgroundWorker.IsBusy)
    { 
    backgroundWorker.CancelAsync();
    Console.ReadLine();
    }  
    }  
    静态无效backgroundWorker_DoWork(对象发送方,DoWorkEventArgs e)
    {  
    对于(int i=0;i<200;i++)
    {  
    if(backgroundWorker.CancellationPending)
    {  
    e、 取消=真;
    返回;
    }  
    后台工作人员报告进度(一);
    睡眠(1000);
    e、 结果=1000;
    }  
    }  
    静态无效backgroundWorker_ProgressChanged(对象发送方,ProgressChangedEventArgs e)
    {  
    Console.WriteLine(“已完成”+e.ProgressPercentage+“%”);
    }  
    静态无效backgroundWorker_RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
    {  
    如果(如已取消)
    {  
    控制台写入线(“操作已取消”);
    }  
    否则如果(例如错误!=null)
    {  
    Console.WriteLine(“进程中的错误:+e.Error”);
    }  
    其他的
    {  
    Console.WriteLine(“操作完成:+e.Result”);
    }  
    }  
    }  
    } 
    
    此外,参考以下链接,您将了解
    背景的概念:


    我发现本教程很有用,它有几个简明的例子:我在点击该链接时出现隐私错误。很抱歉,我发现了这个帖子,但是.net 4.0和4.5添加了一些比
    BackgroundWorker更容易使用的酷东西。希望引导人们使用它。既然这个答案非常古老,请查看
    async
    wait
    。这些是语言集成的方法,可以以更具可读性的方式使用任务。在这些方法中有没有访问DataContext的方法?
    private readonly BackgroundWorker worker = new BackgroundWorker();
    
    worker.DoWork += worker_DoWork;
    worker.RunWorkerCompleted += worker_RunWorkerCompleted;
    
    private void worker_DoWork(object sender, DoWorkEventArgs e)
    {
      // run all background tasks here
    }
    
    private void worker_RunWorkerCompleted(object sender, 
                                               RunWorkerCompletedEventArgs e)
    {
      //update ui once worker complete his work
    }
    
    worker.RunWorkerAsync();
    
    worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
    {
        pd.Close();
        // Get a result from the asynchronous worker
        T t = (t)args.Result
        this.ExampleControl.Text = t.BlaBla;
    };
    
    using System;  
    using System.ComponentModel;   
    using System.Threading;    
    namespace BackGroundWorkerExample  
    {   
        class Program  
        {  
            private static BackgroundWorker backgroundWorker;  
    
            static void Main(string[] args)  
            {  
                backgroundWorker = new BackgroundWorker  
                {  
                    WorkerReportsProgress = true,  
                    WorkerSupportsCancellation = true  
                };  
    
                backgroundWorker.DoWork += backgroundWorker_DoWork;  
                //For the display of operation progress to UI.    
                backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;  
                //After the completation of operation.    
                backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;  
                backgroundWorker.RunWorkerAsync("Press Enter in the next 5 seconds to Cancel operation:");  
    
                Console.ReadLine();  
    
                if (backgroundWorker.IsBusy)  
                { 
                    backgroundWorker.CancelAsync();  
                    Console.ReadLine();  
                }  
            }  
    
            static void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)  
            {  
                for (int i = 0; i < 200; i++)  
                {  
                    if (backgroundWorker.CancellationPending)  
                    {  
                        e.Cancel = true;  
                        return;  
                    }  
    
                    backgroundWorker.ReportProgress(i);  
                    Thread.Sleep(1000);  
                    e.Result = 1000;  
                }  
            }  
    
            static void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)  
            {  
                Console.WriteLine("Completed" + e.ProgressPercentage + "%");  
            }  
    
            static void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)  
            {  
    
                if (e.Cancelled)  
                {  
                    Console.WriteLine("Operation Cancelled");  
                }  
                else if (e.Error != null)  
                {  
                    Console.WriteLine("Error in Process :" + e.Error);  
                }  
                else  
                {  
                    Console.WriteLine("Operation Completed :" + e.Result);  
                }  
            }  
        }  
    }