0

ループのコンテンツをUIに表示しようとしています。まず、(WinFormsを使用して)これに正しい方法でアプローチしているかどうかはわかりませんが、これが私が行っていることです。

foreach (string item in stringArray)
{
        Thread thread = new Thread(delegate()
                              {
                                  UpdatedResultEvent(item);
                              });
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
}

これで十分な情報になるといいのですが、そうでない場合は、ここで詳しく説明します。

Program.cs(WinForm)とlogicClassという別のクラスの2つのクラスがあります。ProgramオブジェクトのインスタンスをlogicClassに渡します。私のlogicClassには、プログラムクラスのメソッドと署名が一致するデリゲートがあります。デリゲートとして渡されるメソッドは

public void UpdateResultsOnScreen(string newContent)
{
txtResults.Text += newContent;
}

エラーメッセージは

クロススレッド操作が無効です:作成されたスレッド以外のスレッドからアクセスされたコントロール

編集

目標は、プログレスバーが機能する方法と同様に、コントロールがリアルタイムで更新されるのを確認することです。現在、それが機能する場合でも、スレッドは、スレッドが完了するまで「結果」を画面に返しません。

4

3 に答える 3

1

ApartmentStateを設定している場合でも、別の(UI以外の)スレッドからアクセスする場合はUIコントロールを呼び出す必要があります。

UpdateResultEventメソッド内でUIコントロールを呼び出すようにしてください。

とにかく、あなたがしていることは良い考えではありません、ThreadPoolまたはParallel.ForEachの使用を検討してください

コードを自動的にスケーリングします。多数のスレッドを生成すると、特にコレクションに多数のアイテムが含まれている場合、パフォーマンスが大幅に低下する可能性があります。

于 2013-03-04T09:50:27.293 に答える
1

これを使用します(WinFormsを使用している場合):

public void UpdateResultsOnScreen(string newContent)
{
    txtResults.BeginInvoke(
        new Action<string>((value) =>
        {
            txtResults.Text += value;
        }),
        newContent);
}

また、animaonlineThreadPoolが言ったように、またはを使用することを検討してParallel.ForEachください。

于 2013-03-04T10:01:39.900 に答える
0

これはどうですか?

 public void UpdateResultsOnScreen(string newContent)
    {
        if(txtResults.InvokeRequired)
        {
            txtResults.Invoke(
                new Action<string>(content => txtResults.Text += content), newContent);
            return;
        }
        txtResults.Text += newContent;
    }
于 2013-03-04T10:05:21.457 に答える