混淆了AsyncCallback的工作原理

时间:2015-08-14 17:52:52

标签: c# asynchronous

我无法理解asynccallbacks的工作原理。我在一个单独的类中有一个方法(调用这个类" Foo"),它要求我传入一个asynccallback方法和一个对象。

此方法应该将某些内容下载为字符串。

public void sampleFunction(AsyncCallback callback, object x)
{
    //download some content as a string
}

然后我有我的asynccallback方法和我调用上述方法的方法:

public static void test(IAsyncResult result)
{
     Console.WriteLine("Reached");

     //Is result the string that should have been downloaded? Confused
     Console.WriteLine(result); 
}

public static void sampleFunction2()
{
    Foo z;
    object t = "hello";
    AsyncCallback callback = new AsyncCallback(test);
    z.sampleFunction(callback, t);
 }

调用sampleFunction2后,没有任何内容打印到控制台。我在做什么/理解错误?

2 个答案:

答案 0 :(得分:2)

我会使用async await关键字而不是使用AsyncCallback的旧(但仍然有效)方法。

public async Task SampleFunction(object x)
{
    await DownloadAsync(); //Download your string using await
    //await will block here until "DownloadAsync" returns. It will return control to the calling method and return here when the await finishes (or comes back to finish the method).
}

public async static CallerMethod()
{
    await SampleFunction(yourObject);
    //The code will continue here while the string is downloading and it will pause the execution to finish the callback (after the await) anytime.
}

将异步方法视为两部分方法。首先是逻辑和回调(await语句之后的代码)。

希望这不太难理解,如果需要,我可以澄清或重新制定。

答案 1 :(得分:0)

我几乎100%确定您在sampleFunction1sampleFunction2

中使用了完全标准化的命名惯例

我相信你的意思。

public class Foo
{
    public void BeginSampleFunction(AsyncCallback callback, object x)
    {
         //download some content as a string
    }

    public string EndSampleFunction(IAsyncResult result)
    {
         //download some content as a string
    }
}

测试代码应为

public void Test()
{
    AsyncCallback callback = a =>
    {
        string result = foo.EndSampleFunction(a);
        Console.WriteLine(result);
    }
    object state = null;
    foo.BeginSampleFunction(callback, state);
}

此模式称为异步编程模型(APM)。它已完全弃用,不应使用。今天我们使用任务异步编程(TAP)。

在TPL中有一种工厂方法,用于将方法从APM转换为TAP。

public async Task Test()
{
    Task<string> task = Task.Factory.FromAsync(foo.BeginSampleFunction, foo.EndSampleFunction, null);
    string result = await task;
    Console.WriteLine(result);
}