我对线程的想法相当陌生,我正在使用BackgroundWorker
, 试图在完成一些工作时显示进度条。这是 的DoWork
事件BackgroundWorker
:
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()
吗?不过,老实说,我不应该在同一个函数中使用其中两个调用。有没有更好的方法来完成我正在尝试做的事情?