2

シリアルポートからデータを取得して処理し、UIに表示するアプリケーションをC#で開発しています。データは5〜50ミリ秒の速度で非常に高速に送信されます。スレッドを使用していなかった前。そのため、アプリケーションは、シリアルポートからデータを取得し、データを処理してUIに表示する単一のアプリスレッドに依存していました。そしてそれはいくつかのデータを失っていました。次に、BackgroundWorkerスレッドの実装を開始して、単一スレッドのオーバーヘッドを取り除き、優れたパフォーマンスを考えました。そして今、私は「このBackgroundWorkerは現在ビジーであり、複数のタスクを同時に実行することはできません「エラー。スレッドはシリアルポートからのデータの速度に対応できないと思います。そのため、「backgroundWorker1.RunWorkerAsync(data);」の実行時にエラーが発生します。このような種類を実装するためのより良いアプローチは何か提案が必要です。シナリオの?

4

3 に答える 3

2

geofftnzは正しいので、少し拡張します。バックグラウンドワーカーは1回だけ起動し、ReportProgressを使用してデータをGUIスレッドにフィードバックする必要があります。ワーカースレッドは次のようになります。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackGroundWorker;
    while(!e.CancellationPending)
    {
        ResultObject ro = new ResultObject();  // your own type here, obviously
        //Process and store some data in ro;
        worker.ReportProgress(0, ro);
        //Do not modify ro after reporting progress to avoid threading issues
    }
}

GUIから、ProgressChangedイベントに登録し、ワーカーを1回だけ起動します。

于 2009-07-29T00:20:25.520 に答える
0

問題は、前の操作が完了する前に backgroundWorker1.RunWorkerAsync() を呼び出していることです。

おそらく必要なのは、シリアル ポートを読み取り、データをバッファリングし、データが利用可能であることをメイン UI スレッドに通知する単一のスレッドです。

于 2009-07-28T23:30:37.723 に答える
0

これを追加して、バックグラウンド ワーカーが一度に 1 つのジョブのみを実行するようにしてください。

if(!backgroundWorker1.IsBusy)
    backgroundWorker1.RunWorkerAysnc();

現在のジョブをキャンセルすることもできます。コード サンプルは次のとおりです。

    private void WhereBackworkerStarts()
    {
        backgroundWorker.WorkerSupportsCancellation = true;

        if (backgroundWorker.IsBusy)
            backgroundWorker.CancelAsync();
        else
            backgroundWorker.RunWorkerAsync();
    }

    // Events
    static void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        for(int i = 0; i < int.MaxValue; i++)
        {
            if (backgroundWorker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }

            // Do work here
        }
        e.Result = MyResult;
    }

    static void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // Deal with results
    }
于 2009-07-28T23:41:11.417 に答える