繁体   English   中英

对象由不同的线程拥有

[英]Object owned by a different thread

我对线程的想法相当新,我正在使用BackgroundWorker ,尝试在完成一些工作时显示进度条。 这是BackgroundWorkerDoWork事件:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM