日期:2014-05-17  浏览次数:20695 次

请教一个.net 4.5 async 的问题??
直接上Code比较直观(稍作说明):
1:自定义Awaiter

public class DemoAwaiter : INotifyCompletion
{

public bool IsCompleted
{
get
{
return true;
}
}

public void OnCompleted(Action continuation)
{
continuation();
}

public int GetResult()
{
return 1;
}
}


2:扩展实现对象

public static class AsyncExtensions
{
public static TaskAwaiter GetAwaiter(this int d)
{
return Task.Delay(d).GetAwaiter();
}

public static DemoAwaiter GetAwaiter(this DateTime time)
{
return new DemoAwaiter();
}
}




3:结果对比
public static async Task GetTaskInt()
{
DateTime time = DateTime.Now;
await time;
Console.WriteLine(123);
}

public static async Task GetTaskTime()
{
DateTime time = DateTime.Now;
await time;
Console.WriteLine(123);
}

3.1:运行 GetTaskInt(); 先输出 "i am continue job" ,然后输入 "123" (预期正常异步结果)
3.2:运行 GetTaskTime() 先输入"123",然后输入 "i am continue job" (这里就是问题,感觉没有异步执行??

请大家看下为什么?
本人推测:会不会是task.Delay 新开启了一个线程哪?


------解决方案--------------------
引用:
你的这个代码“await 1000;”能执行?难道是我孤陋寡闻?
应该是这样写:
await Task.Delay(1000);

await 关键字必须紧跟返回Task或Task<T>类型的方法后面,你直接跟一个数字或一个日期,居然不报错?而且这和你1、2两段代码完全无关了。


GetAwaiter 返回TaskAwaiter可以修改await。可以执行。

------解决方案--------------------
你自己实现的代码中没有使用到任何多线程的部分啊,而Task类就是对多线程操作的一个封装,Task.Delay就是多线程中的等待,因此调用那个进行等待不会阻碍当前线程,只是子线程被阻塞了。当然,这对于一般用途来说没任何意义,主要用在async修饰的方法中,由于方法本身就是多线程的情况,那么系统就会在执行同步方法的过程中,遇到多线程等待时,停止同步方法的执行,直到等待的时间过去了,才去执行后面的同步方法,但是这等待的过程不会阻塞当前线程,表现为用户界面不会卡住。