2015-08-14 80 views
-1

我无法理解asynccallbacks是如何工作的。我有一个方法在一个单独的类中(称这个类为“Foo”),它需要我传入一个asynccallback方法和一个对象。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,没有打印到控制台后。我在做什么/理解错误?

+0

'result'的类型是什么? –

+0

@SKLAK如果你不确定异步如何工作,然后做一个谷歌搜索也阅读这里发布的答案解释http://stackoverflow.com/questions/24953808/write-your-own-async-method – MethodMan

+0

@MrLister它是一些只包含一个取消异步操作的方法的接口。 – SKLAK

回答

0

我相信几乎100%你已经完全bastardized使用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); 
} 
+0

对不起,这是非常新的。感谢修复 – SKLAK

+0

回调被调用的地方在哪里?如果你做foo.BeginSampleFunction,你将参数传递给一个无所事事的函数。没有人叫回调。这是行不通的。您需要一个委托并在委托上进行begininvoke。 –

+0

@PhilipStuyck将回调传递给'BeginXXX'方法的一点是,当它完成时,它会调用回调函数。没有委托可以调用'BeginInvoke'。这不是线索。这是异步I/O。 – Aron

1

asynccallback是一个将在异步操作完成时调用的回调函数。它通常作为参数传递给名称以begin开头的方法。或者你使用委托,做一个BeginInvoke的

整个过程是由微软在这里详细解释说:https://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.110).aspx

寻找在我提供的链接的最后一个例子。

+0

一旦sampleFunction完成,不会测试被调用吗? – SKLAK

+0

当然不是,如果你有一个委托给该方法,然后做一个begininvoke然后传递回调,它会被调用。阅读链接中的最后一个例子,我提供了它正是你想要做的。 –

+0

我明白了,那么应该由sampleFunction下载的字符串会发生什么变化? – SKLAK

2

我会使用异步等待关键字,而不是使用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语句之后的代码)。

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