我有一些代码可以创建一个任务,它会像这样执行一些缓慢的工作:
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/