直接上Code比较直观(稍作说明):
1:自定义Awaiterpublic 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 新开启了一个线程哪?

解决方案 »

  1.   

    你给的代码有问题,执行必定报错,除非是你精简的时候把关键部分删除了。就你的推测,我可以直接告诉你,Task.Delay是多线程等待,和Thread.Sleep不一样,后者是当前线程等待。虽然都会在等待后进行后续操作,不过Task.Delay会将后续操作包装到回调函数中,这个你是看不到的,编译的时候自动处理。
      

  2.   

    sorry,将第三部分重新提交下
    public class Class1
        {
            public static async Task GetTaskInt()
            {
                await 1000;
                Console.WriteLine(123);
            }        public static async Task GetTaskTime()
            {
                DateTime time = DateTime.Now;
                await time;
                Console.WriteLine(123);
            }        public static void Main()
            {
                GetTaskTime();
                Console.WriteLine("i am continue job");
                GetTaskInt();
                Console.WriteLine("i am continue job");
                Console.Read();
            }        
            
        }
      

  3.   

    推测楼主想改造await,一个按照时间等待,一个按照毫秒数等待DemoAwaiter 没看出来如何使用time的。是想实现如下逻辑?public static TaskAwaiter GetAwaiter(this DateTime time)
    {
         return Task.Delay(time - DateTime.Now).GetAwaiter();
    }
      

  4.   

    关键是我想实现一自定义的TaskAwaiter,出现的问题就是红色字体部分,为什么我的实现,continue的job是在await操作之后执行的?
      

  5.   

    你的这个代码“await 1000;”能执行?难道是我孤陋寡闻?
    应该是这样写:
    await Task.Delay(1000);
    await 关键字必须紧跟返回Task或Task<T>类型的方法后面,你直接跟一个数字或一个日期,居然不报错?而且这和你1、2两段代码完全无关了。
      

  6.   


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

  7.   

    关键是我想实现一自定义的TaskAwaiter,出现的问题就是红色字体部分,为什么我的实现,continue的job是在await操作之后执行的?GetTaskTime 里没看到具体怎么使用time的,无法判断你的正确逻辑
      

  8.   

    不好意思...这个可能是我没讲清楚,2楼补充的东西要跟我刚开始写的东西放在一起执行的.关键是我想实现一自定义的TaskAwaiter,出现的问题就是红色字体部分,为什么我的实现,continue的job是在await操作之后执行的?GetTaskTime 里没看到具体怎么使用time的,无法判断你的正确逻辑可能是我的代码定义的东西引起了歧义,先说下我写这段code的背景:
    就是为了想自己实现一让某个对象支持 await 操作,并且使用自定义的Awaiter(此处定义的DateTime只是为了偷懒随便找来一个对象来验证自定义的Awaiter即DemoAwaiter)。
    问题:
    但是结果却发现我自己写的代码跟使用.net 提供的TaskAwaiter所实现的代码执行顺利不一样....
    感觉我自己实现的代码就是同步在执行,而使用.net 提供的则是异步在执行,所以问题就来了,这是为什么那??
    那根据楼上所说 Task.Delay 是多线程的操作.那么根据我自己对.net 4.5 async 的理解,await 后边的的东西应该有编译器自己创建了一个状态机去做工作的。这个应该跟多线程没关系吧?请指教.
      

  9.   

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