2

ネットワーク経由で情報を受信して​​処理するサーバー アプリケーションがあります。サーバーはマルチスレッドであり、一度に複数のソケットを処理します。スレッドは、対応するコールバック関数によって連鎖された BeginInvoke および EndInvoke スタイルのメソッドを介して、私の制御なしで作成されます。

メイン GUI に加えて、現在接続されているソケットを説明するアイテムが取り込まれた ListBox アイテムを表示するフォームを作成しようとしています。したがって、私が基本的にやろうとしているのは、適切なコールバック関数が実行されているスレッドから、Add() 関数を使用して ListBox にアイテムを追加することです。Controls プロパティを介してフォーム コントロールにアクセスしています - IE:

(ListBox)c.Controls["listBox1"].Items.Add();

当然のことながら、関数を呼び出すだけではありません。ここと Web で見つけたスレッド間で通信するMethodInvoker方法delegateをいくつか試しました。私のコントロールが作成されたスレッド以外のスレッドからアクセスされたことを示す同じ例外。Invoke()BeginInvoke()

何かご意見は?

4

3 に答える 3

5

私はいつもこれらの線に沿って何かを使用してきました:

        c = <your control>
        if (c.InvokeRequired)
        {
            c.BeginInvoke((MethodInvoker)delegate
            {
                //do something with c
            });
        }
        else
        {
            //do something with c
        }

また、ヘルパー拡張メソッドをたくさん書いて... 助けました。

using System;
using System.ComponentModel;
public static class CrossThreadHelper
{
    public static bool CrossThread<T,R>(this ISynchronizeInvoke value, Action<T, R> action, T sender, R e)
    {
        if (value.InvokeRequired)
        {
            value.BeginInvoke(action, new object[] { sender, e });
        }

        return value.InvokeRequired;
    }
}

次のように使用します。

     private void OnServerMessageReceived(object sender, ClientStateArgs e)
    {
        if (this.CrossThread((se, ev) => OnServerMessageReceived(se, ev), sender, e)) return;
        this.statusTextBox.Text += string.Format("Message Received From: {0}\r\n", e.ClientState);
    }
于 2008-10-23T10:46:14.663 に答える
2

BeginInvoke または Invoke を使用すると問題なく動作するはずです。問題を示す短いが完全なプログラムを投稿できますか? 実際にはサーバー側のものを必要としないものを作成できるはずです-着信接続を受信するように「ふりをする」スレッドがたくさんあるだけです。

于 2008-10-23T10:44:41.000 に答える
2

コントロールを作成したスレッドでデリゲートを呼び出すには、アクセスしている ListBox コントロールで Invoke (または BeginInvoke) を呼び出す必要があります。

ListBox listBox = c.Controls["listBox1"] as ListBox;
if(listBox != null)
{
   listBox.Invoke(...);
}
于 2008-10-23T10:47:32.367 に答える