在c#中将数据传递给回调方法(通过BeginInvoke)

时间:2009-03-29 22:44:37

标签: c# .net multithreading

我有以下代码:

    delegate int doStuffDel(int instanceNo, int sleepTime, int repeatCount);
    string result;

    private int doStuff(int instanceNo, int sleepTime, int repeatCount)
    {
        for (int i = 0; i < repeatCount; i++)
        {
            Console.Write(instanceNo);
            Thread.Sleep(sleepTime);
        }
        result = instanceNo + " repeated " + repeatCount;
        return instanceNo;
    }

    private void button3_Click(object sender, EventArgs e)
    {
        doStuffDel del = doStuff;
        IAsyncResult ar = del.BeginInvoke(3, 120, 50, finishedCallback, result);
    }

    private void finishedCallback(IAsyncResult ar)
    {
        Console.WriteLine("Done. The result was " + ar.AsyncState.ToString());
    }

我认为res.AsyncState将返回字符串,作为BeginInvoke调用中的最后一个参数传递,但它为null。有人知道为什么吗?

PS,我知道我可以将del作为BeginInvoke中的最后一个参数传递,然后在回调中调用EndInvoke,从doStuff方法中获取一些结果,或者我可以从类中获取字符串val! - 但我很惊讶AsyncResult对象上的AsyncState为null ...

3 个答案:

答案 0 :(得分:8)

ar.AsyncState的值是您最初将其传递给BeginInvoke时的结果值。事实上,当你通过它时,你使用result的值并不意味着它“绑定”到结果变量。它只是将result变量传递给它时的值。

要查看此内容,请在调用result之前将BeginInvoke设置为某个测试值,或者只是传递字符串文字。无论哪种方式,您都会在回调中获得该值。

另一方面,您的回调和原始委托都具有相同的目标对象,因此您可以在回调中使用use result并且它将具有您想要的值 - 这是维持状态的另一种方式。

答案 1 :(得分:1)

当您调用BeginInvoke时,它会被传入。那时,结果为空。如果您在通话前设置结果,您将在回调中看到它。

答案 2 :(得分:1)

问题是您传递了result - (doStuff之前)nullresultdoStuff的更新不会影响异步状态。