簡體   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