[英]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.