单击选项卡并调用Parallel.Invoke时出现InvalidOperationException?

时间:2016-04-06 14:51:30

标签: c# multithreading winforms thread-safety task

背景

我是一个非常擅长在C#中进行线程/并发操作的人,我正在努力使用跨线程的GUI应用程序。现在我遇到了在运行时被抛出的异常,我不知道如何处理。首先,我将提供正在发生的事情的背景,然后我将描述我试图调试的内容。

我有一项任务可以进行大量计算。

// display dump information
displayDumpTask = readingDumpTask.ContinueWith(
    delegate
    {
        Parallel.Invoke
        (
            () => this.DisplayEntries(),
            () => this.DisplayDump()
        );
    }
, TaskScheduler.FromCurrentSynchronizationContext());

完成此任务后,我想一次做两件事。我按照以下方式实施这个过程......

private void DisplayEntries()
{
    UpdateUIDelegate myDel = new UpdateUIDelegate(this.DisplayEntries);

    if (this.InvokeRequired)
    {
        this.BeginInvoke(myDel);
    }

    // fills some data into labels on the GUI
}

正在委派的两种方法,按以下方式工作......

方法#1

private void DisplayDump()
{
    UpdateUIDelegate myDel = new UpdateUIDelegate(this.DisplayDump);

    if (this.InvokeRequired)
    {
        this.BeginInvoke(myDel);
    }

    // fills some data into a RTB on the GUI
}

方法#2

InvalidOperationException

我想说清楚方法#1没有使用方法#1所使用的任何控件。

问题陈述

这里的问题是,一旦我尝试从DisplayDump函数内部访问控件,我就会得到DisplayDump。当我点击转储标签时,我只会遇到此异常,如下所示。

Form Design

我认为这与DisplayDump方法正在访问位于转储标签内的文本框这一事实有关。现在,当我在导航标签上时,我从未遇到任何问题,一切都安然无恙。

尝试调试

我今天早上才发现如何看到并行任务调试窗口,更别说真的知道如何使用它来解决我的问题了。所以,我已经从 Parallel.Invoke 块中删除了一个方法调用,我发现在哪个选项卡上无关紧要,在这种情况下我永远不会得到异常({{ 1}}总是有效的)。但是,只要我在Parallel语句中有两个操作,就会出现问题。所以...到目前为止,我所知道的是它与Parallel.Invoke

有关

enter image description here

1 个答案:

答案 0 :(得分:0)

调用BeginInvoke后,您的方法应该返回。如果你没有返回,那么将在非UI线程上访问GUI,你将获得InvalidOperationException。

private void DisplayEntries()
{
    UpdateUIDelegate myDel = new UpdateUIDelegate(this.DisplayEntries);

    if (this.InvokeRequired)
    {
        this.BeginInvoke(myDel);
        return;  // ** change here
    }

    // fills some data into labels on the GUI
}