-2

テキストボックスにコンテンツを非同期で表示したいですか? 以下にリストされている私のコードのバグを知っている人はいますか? テキストボックス内のテキストを実装したいのですが、新しい値で毎秒更新されますか? また、コントローラーの呼び出しメソッドを呼び出す前に毎回 InvokeRequired をチェックする理由を知りたいですか?

        private void Counting(int Num)
    {

        int i = 0;
        string counter = null;
        while (i < Num)
        {
            Thread.Sleep(1000);
            counter = string.Format(" {0}", i);
            tbxStatus.BeginInvoke(new UpdateStatusDelegate(UpdateStatus), new string[] { counter });
        }

    }

    public void UpdateStatus(string data)
    { 
        tbxStatus.Text += data;
    }

    public delegate void UpdateStatusDelegate(string data);

    public delegate void CountDelegate(int num);

    private void btnStart_Click(object sender, EventArgs e)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new CountDelegate(Counting), new object[] { 5 });
        }
        else
            Counting(5);
    }

ありがとう

4

2 に答える 2

1

InvokeRequiredテストはデリゲート内にある必要があります。

public void UpdateStatus(string data)
{
    if (this.tbxStatus.InvokeRequired)
    {
        UpdateStatusDelegate d = new UpdateStatusDelegate(UpdateStatus);
        this.Invoke(d, new object[] { data });
    }
    else
    {
        this.tbxStatus.Text = data;
    }
}

次の拡張メソッドを使用すると、これをはるかに簡単かつきれいに見せることもできます。

public static TResult SafeInvoke(this T isi, Func call) where T : ISynchronizeInvoke
{
    if (isi.InvokeRequired) {
        IAsyncResult result = isi.BeginInvoke(call, new object[] { isi });
        object endResult = isi.EndInvoke(result); return (TResult)endResult;
    }
    else
        return call(isi);
}

public static void SafeInvoke(this T isi, Action call) where T : ISynchronizeInvoke
{
    if (isi.InvokeRequired) isi.BeginInvoke(call, new object[] { isi });
    else
        call(isi);
}

したがって、UI スレッドで定義したメソッド (フォーム インスタンスで定義されたメソッドなど) を呼び出したい場合は、次のコードを使用して呼び出すことができます (デリゲートなどを作成する必要はありません)。

formInstance.SafeInvoke(f => f.myFormMethod("parameter1","parameter2"));

あなたの場合、次のことができます:

formInstance.SafeInvoke(f => f.UpdateStatus(myCounterInt.toString));

またはそのようなもの。

私はブログでこれを使用することについて書きましたが、この CodeProject の記事について書いていたので、クレジットを与えないでください。

于 2012-07-27T03:58:22.460 に答える