我如何使用异步委托?

时间:2015-10-30 18:08:59

标签: c# asynchronous delegates

我有一个C#windows窗体应用程序。我的一个按钮有这个事件:

    private void btnNToOne_Click(object sender, EventArgs e)
    {
        int value = (int)numUpToThis.Value;
        textResult.Text = Program.asyncCall(value, 2).ToString();
    }

它所调用的方法就是这个:

    public delegate int DelegateWithParameters(int numar, int tipAlgoritm);
    public static int asyncCall(int numar, int tipAlgoritm)
    {
        DelegateWithParameters delFoo = new DelegateWithParameters(calcPrim);
        IAsyncResult tag = delFoo.BeginInvoke(numar, tipAlgoritm, null, null);
        while (tag.IsCompleted == false)
        {
            Thread.Sleep(250);
        }
        int intResult = delFoo.EndInvoke(tag);
        return intResult;

    }

问题是它一直阻塞我的用户界面,所以我显然做错了什么。我该如何使用异步委托?有什么提示吗?

1 个答案:

答案 0 :(得分:-2)

以下是此特殊情况的快速示例,您可以在需要此类内容时使用。

首先,你不能在方法中封装整个异步逻辑,因为结果不能用return语句提供,所以只提供同步方法

static class MyUtils
{
    public static int CalcPrim(int numar, int tipAlgoritm)
    {
        // ...
    }
}

然后在表单中使用以下内容

private void btnNToOne_Click(object sender, EventArgs e)
{
    int value = (int)numUpToThis.Value;
    Action<int> processResult = result =>
    {
        // Do whatever you like with the result
        textResult.Text = result.ToString();
    }
    Func<int, int, int> asyncCall = MyUtils.CalcPrim;
    asyncCall.BeginInvoke(value, 2, ar =>
    {
        // This is the callback called when the async call completed
        // First take the result
        int result = asyncCall.EndInvoke(ar);
        // Note that the callback most probably will called on a non UI thread,
        // so make sure to process it on the UI thread
        if (InvokeRequired)
            Invoke(processResult, result);
        else
            processResult(result);
    }, null);
}

最后,仅用于比较,等效async/await代码

private async void btnNToOne_Click(object sender, EventArgs e)
{
    int value = (int)numUpToThis.Value;
    int result = await Task.Run(() => MyUtils.CalcPrim(value, 2)); 
    textResult.Text = result.ToString();
}