繁体   English   中英

如何使backgroundworker在WPF应用程序中工作

[英]How to make backgroundworker work in WPF application

我是编程和WPF架构的新手。 我有一个使用backgroundworker类的WPF应用程序。 但是,它始终抛出错误“调用线程必须是sta,因为许多ui组件需要这个”。 我需要添加STAThread属性我的main方法。 但我不知道该怎么做。

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

            this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();           

            InitializeBackgroundWorker();
            Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
            tabItemList.CollectionChanged += this.TabCollectionChanged;
        }
}


 private void InitializeBackgroundWorker()
        {
            backgroundWorker1.DoWork +=
                new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker1.RunWorkerCompleted +=
                new RunWorkerCompletedEventHandler(
            backgroundWorker1_RunWorkerCompleted);
            backgroundWorker1.ProgressChanged +=
                new ProgressChangedEventHandler(
            backgroundWorker1_ProgressChanged);
        }

        // This event handler is where the actual, 
        // potentially time-consuming work is done. 
        private void backgroundWorker1_DoWork(object sender,
            DoWorkEventArgs e)
        {
            // Get the BackgroundWorker that raised this event.
            BackgroundWorker worker = sender as BackgroundWorker;

            // Assign the result of the computation 
            // to the Result property of the DoWorkEventArgs 
            // object. This is will be available to the  
            // RunWorkerCompleted eventhandler.
            //e.Result = AddTabitem((int)e.Argument, worker, e);
            AddTabitem((string)e.Argument, worker, e);
        }

 void AddTabitem(string filePath, BackgroundWorker worker, DoWorkEventArgs e)
        {
            if (File.Exists(filePath))
            {
//This line which throws error "the calling thread must be sta because many ui components require this"
                RichTextBox mcRTB = new RichTextBox();
                rtbList.Add(mcRTB);
}

你必须在线程启动之前设置ApartmentState。

http://blogs.msdn.com/b/jfoscoding/archive/2005/04/07/406341.aspx

要在WPF应用程序上设置公寓状态,
[STAThread]属性添加到您的应用程序,如下所示

public partial class App : Application
{
    App()
    {
        InitializeComponent();
    }

    [STAThread]
    static void Main()
    {
        Window1 window = new Window1();
        App app = new App();
        app.Run(window);
    }
}

编辑:

我对STAThread有点了解,因为这不是你的问题。

在查看更新的后台工作程序代码之后,您尝试从后台工作程序线程更新UI。 正如您所经历的那样,这是行不通的。 你有几个选择:

1)而不是直接更新RichTextBox,而是更新您正在更新的数据绑定到该属性的变量。 有关数据绑定的概述,请参阅此文章,因为您已经声明自己是WPF的新手: http//msdn.microsoft.com/en-us/library/ms752347( v = vs.110).aspx

2)使用Invoke而不是直接设置属性。 无论如何,您可能需要为选项1执行此操作。 这可能是您最直接的快速解决方案。 这是WPF调度程序的一个很好的理由,这是调用业务所需要的: http//tech.pro/tutorial/800/working-with-the-wpf-dispatcher

它的工作方式如下:mcRTB.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,new Action(delegate(){mcRTB.Text =“hello”;}));

以上是更改财产。 您可以调整它以调用rtbList的.Add方法。

3)想避免调用? 使用您的后台工作人员的报告进度! 当你在BW中告诉它时会触发此事件,然后你可以在主UI线程上做一些工作,而不必担心调用东西。

初始化BW时,请在此处添加:

backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.ProgressChanged += new ProgressChanged EventHandler(backgroundWorker1_ProgressChanged);

然后在您的回调中(或者使用+ =为您自动处理),您可以在UI线程上进行操作。 您可以通过执行以下操作告诉您的BW报告一些进展:

// the int in the first parameter is arbitrary
// the object can be any object. This is how you pass actual data to your call back
backgroundWorker1.ReportProgress(1,new object()) 

以下是关于报告进度的很好的阅读: http//msdn.microsoft.com/en-us/library/a3zbdb1t(v = vs.110).aspx

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM