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