c# - 如何创建一个在体内使用 await 的 Task,其行为与调用 Wait 时的同步版本相同?

标签 c# .net asynchronous .net-4.5 async-await

我有一些代码可以创建一个任务,它会像这样执行一些缓慢的工作:

public static Task wait1()
{
    return new Task(() =>
    {
        Console.WriteLine("Waiting...");
        Thread.Sleep(10000);
        Console.WriteLine("Done!");
    });
}

在实际实现中,Thread.Sleep 实际上是一个网络服务调用。我想更改方法的主体可以使用等待(因此它在网络访问/ sleep 期间不会消耗线程)。我的第一次尝试(基于霰弹枪调试编译错误)是这样的:

public static Task wait2()
{
    return new Task(async () =>
    {
        Console.WriteLine("Waiting...");
        await Task.Delay(10000);
        Console.WriteLine("Done!");
    });
}

但是;此任务的行为似乎与第一个任务不同,因为当我在其上调用 .Wait() 时;它立即返回。

下面是显示差异的完整示例(控制台应用程序)(应用程序将在第二个任务开始时立即结束)。

我需要做什么才能调用 Start 和 Wait 来调用恰好在其中使用 await 的代码的任务?任务排队并稍后由代理执行,因此任务不能自动启动是至关重要的。

class Program
{
    static void Main(string[] args)
    {
        var w1 = wait1();
        w1.Start();
        w1.Wait(); // This waits 110 seconds

        var w2 = wait2();
        w2.Start();
        w2.Wait(); // This returns immediately
    }

    public static Task wait1()
    {
        return new Task(() =>
        {
            Console.WriteLine("Waiting...");
            Thread.Sleep(10000);
            Console.WriteLine("Done!");
        });
    }

    public static Task wait2()
    {
        return new Task(async () =>
        {
            Console.WriteLine("Waiting...");
            await Task.Delay(10000);
            Console.WriteLine("Done!");
        });
    }
}

最佳答案

这似乎是不可能的!参见 alexm's answer here :

Tasks returned by async methods are always hot i.e. they are created in Running state.

:-(

我通过让代理队列 Func<Task>s 解决了这个问题相反,接收任务的重载只是排队 () => task .然后;当任务出列时,我会检查它是否未运行,如果是,则启动它:

var currentTask = currentTaskFunction();
if (currentTask.Status == TaskStatus.Created)
    currentTask.Start();

必须执行此操作似乎有点笨拙(如果这个简单的解决方法有效;为什么对异步方法的原始限制总是被热创建?),但它似乎对我有用:-)

关于c# - 如何创建一个在体内使用 await 的 Task,其行为与调用 Wait 时的同步版本相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17514442/

相关文章:

c# - 为灰度图像着色

c# - 在 64 位上没有修改权限的情况下,从 UNC 路径加载 .Net 程序集失败

c# - DataGridView 处理列重新排序事件

.net - 在 WCF 服务中,如何公开只能访问某些方法的第二个端点?

c# - 为什么暂停/中止线程不好?

asynchronous - Dart-为什么我必须等待这个.fold电话

c# - 找不到 OpenAPI 描述

node.js - 使用 Async/Await 拒绝/解决 - 错误处理

javascript - Javascript 中嵌套函数 "Class"结构中的变量范围

c# - INotifyPropertyChanged 不会通过 View 模型