首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的TCS不等待?

为什么我的TCS不等待?
EN

Stack Overflow用户
提问于 2015-09-25 15:30:20
回答 3查看 1K关注 0票数 9

async关键字确实会导致CIL发生更改(即使方法中没有等待),但它主要是为了允许await出现。

但我没想到会发生以下情况:

代码语言:javascript
复制
static void Main(string[] args)
{
    Task t = Go();
    t.Wait();
}

static async Task Go()
{
    Console.WriteLine(1);
    await AAA(3000);
    Console.WriteLine(2);
}


static  Task<object> AAA(int a) // <--- No `async`
{
    TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
    Task.Delay(a).ContinueWith(b => tcs.SetResult(null));
    return tcs.Task;
}

这张印刷品:

代码语言:javascript
复制
1
(wait)
2

但如果我改变了

代码语言:javascript
复制
static  Task<object> AAA(int a) 

代码语言:javascript
复制
static async  Task<object> AAA(int a) 

它打印:

代码语言:javascript
复制
1
2
(no wait)

问题

我为什么不看一下延迟时间?TCS只在3秒后被解析。同时,这一任务尚未解决,应等待。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-09-25 15:38:02

如果没有async关键字,您将从AAA返回TaskCompletionSource的任务,因此您将等待它完成(这将在延迟完成后发生)。

但是,添加async关键字时,从该方法返回的任务是状态机的任务,它同步完成。该任务包含(因此)TaskCompletionSource的任务,但这不是您正在等待的任务。

如果希望该方法等待TaskCompletionSource的任务,则可以等待Task<Task>的内部任务。

代码语言:javascript
复制
await ((Task) await AAA(3000));

或者等待TaskCompletionSource,而不是返回它:

代码语言:javascript
复制
async Task AAA(int a)
{
    TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
    Task.Delay(a).ContinueWith(b => tcs.SetResult(null));
    await tcs.Task;
}

或者更好的是,仅仅等待Task.Delay本身:

代码语言:javascript
复制
async Task<object> AAA(int a)
{
    await Task.Delay(a);
    return null;
}
票数 8
EN

Stack Overflow用户

发布于 2015-09-25 15:37:21

因为当您使用返回类型的Task从异步方法返回Task<object>时,您可以在任务(期望等待的任务)内部获得Task<Task>。你应该做的是:

代码语言:javascript
复制
static async Task<object> AAA(int a)
{
  await Task.Delay(a);
  return null;
}

总之,尽量避免在一种方法中将异步等待和指示任务操作混合在一起。

票数 6
EN

Stack Overflow用户

发布于 2015-09-25 15:40:58

正如Serg所提到的,在Visual中查看这个示例:

代码语言:javascript
复制
        static async Task<int> AAA(int a) // <--- No `async`
        {
             TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
             Task.Delay(a).ContinueWith(b =>
             {
                  tcs.SetResult(1);
             });
             return tcs.Task;
        }

您将得到这样的错误:

,因为这是一个异步方法,所以返回表达式必须是'int‘类型,而不是'Task',因为您的方法将同步运行。这就是为什么它需要返回int,而不是Task

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32785678

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档