[英]Object owned by a different thread
我對線程的想法相當新,我正在使用BackgroundWorker
,嘗試在完成一些工作時顯示進度條。 這是BackgroundWorker
的DoWork
事件:
private void BackgroundWorker1DoWork(object sender, DoWorkEventArgs e)
{
SetDateStartEndTimeForReport();
try
{
PopulateGrid();
}
catch (Exception ex)
{
Logger.Error(ex.Message);
MessageBox.Show(ex.Message);
return;
}
}
現在,在我的SetDateStartEndTimeForReport()
,我得到一個InvalidOperationException
:
private void SetDateStartEndTimeForReport()
{
Logger.Info("Setting the chosen date and/or start/end times for report...");
// Quite possibly the best yo-yo code I've ever written
// "Look, I'm a string. Nope, I'm a DateTime. Tricked you again, I'm a string."
var reportDate = Convert.ToDateTime(cmbDateSelecter.SelectedValue.ToString()).ToString("yyyy-MM-dd"); // Exception occurs here
Report.Date = reportDate;
if (chkboxTimeFrame.IsChecked == true)
{
Report.StartTime = timeStart.Value.Value.ToString(reportDate + " HH:mm");
Report.EndTime = timeEnd.Value.Value.ToString(reportDate + " HH:mm");
}
Logger.Info("Date and/or start/end times set");
}
例外情況說明:
調用線程無法訪問此對象,因為另一個線程擁有它。
所以,我做了一些研究,並發現了關於this.Dispatcher.Invoke((Action)(()
。現在,當我包裝SetDateStartEndTimeForReport();
在那:
this.Dispatcher.Invoke((Action)(() =>
{
SetDateStartEndTimeForReport();
}));
我的PopulateGrid()
拋出相同的異常。 現在,我可以將該方法包裝在同一個Dispatcher.Invoke()
,這會使問題消失。 但是,我覺得好像我錯過了一些更優雅的東西。 在函數調用時,UI元素都不應該被其他任何東西使用。 我的問題是,我可以在同一個Dispatcher.Invoke()
包裝兩個方法嗎? 雖然,老實說我覺得我不應該在同一個函數中使用其中兩個調用。 有沒有更好的方法去做我正在嘗試做的事情?
您可以通過后台工作程序的ProgressChanged事件傳回數據。 這將封送回UI線程。 該文檔通過調用ReportProgress讓您知道您調用此事件
請注意, BackgroundWorker's
應該只在其DoWork
執行業務邏輯。 如果您所做的只是更新UI,那么您無法在后台線程上執行此操作。 如果需要檢索數據,那么可以使用后台工作程序將其加載到內存中,完成后,如果連接了它,它將調用OnRunWorkerCompleted事件(將在UI線程上)
如果你想要某種方法來處理它,那么Invoke
是唯一的另一種方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.