0

私はC#とすべてのスレッドに慣れていないので、現時点で「クロススレッド操作が無効なエラー」になっています。

コードの関連部分は次のとおりです。

    private LinkedList<string> _statusList = new LinkedList<string>();

    private void ReportToStatus(string message)
    {
        _statusList.AddLast(message);\
        // textStatus is a textbox.
        // And this is the exact line that is giving the error:
        textStatus.Lines = _statusList.ToArray();
    }

    private void RunTest()
    {
        // ...

        // Run the test in the background worker.
        bgwTest.RunWorkerAsync(testCase);
    }

    private void bgwTest_DoWork(object sender, DoWorkEventArgs e)
    {
        TestCase testCase = e.Argument as TestCase;

        // ...

        // Run the test.
        switch (testCase.TestType)
        {
            case "TestA":    TestA(testCase);
                             break;
        }

        e.Result = testCase;
    }

    private void TestA(TestCase testCase)
    {
        // ...

            PrintStatistic(statisticsForCoil, testCase.OutputFile);
        }
    }

    private void PrintStatistic(int[] statistics, string outputFile)
    {
        // ...

        ReportToStatus(result);
    }

どうすればいいですか?

4

3 に答える 3

1

にはBackgroundWorker、UIを更新するための専用のメカニズム BackgroundWorker.ReportProgressがあります。たとえば、コードでは次のようになります。

private void ReportToStatus(string message)
{
    _statusList.AddLast(message);
    // textStatus is a textbox.
    // And this is the exact line that is giving the error:
    bgwTest.ReportProgress(0, _statusList.ToArray());
}

//Assuming this is the method handling bgwTest's ProgressChanged event
private void bgwTest_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
     textStatus.Lines = (string[])(e.UserState);
}
于 2012-08-20T14:32:56.117 に答える
1

_statusList に問題があるようです。別のスレッドから書き込むことはできません。読み取りのみです。

MSDNから

「LinkedList クラスは、連鎖、分割、サイクル、またはリストを一貫性のない状態にする可能性のあるその他の機能をサポートしていません。リストは単一のスレッドで一貫性を保ちます。LinkedList でサポートされている唯一のマルチスレッド シナリオは、マルチスレッド読み取り操作です。」

また、バックグラウンド スレッドから UI にアクセスすることはできません。ディスパッチャーを使用して、UI スレッドに対する操作を呼び出す必要があります。これを行うには、コードを次のようにする必要があります

WPF

    Application.Current.Dispatcher.Invoke(new Action(delegate
                                   {
                                        textStatus.Lines = _statusList.ToArray();
                                   }));

Winフォーム

    textStatus.Invoke(new Action(delegate
                                   {
                                        textStatus.Lines = _statusList.ToArray();
                                   }));
于 2012-08-20T03:00:06.527 に答える
0

バックグラウンドワーカーからUIを更新しようとしているため、その例外が発生します。代わりに、ディスパッチャーを使用して更新をスケジュールできます。または、より理想的には、バックグラウンドワーカーを使用して「バックグラウンド」作業のみを実行し、RunWorkerCompletedイベントが発生したときにUI更新を実行します。

于 2012-08-20T02:52:58.287 に答える