我陷入了一些我认为如此简单的事情,它让我脱离了自己。
我需要在某个时候声明一个任务并稍后再运行,我想到了:
Task T1 { get; set; }
public async Task CreateAndAwaitAsync()
{
T1 = new Task(() => {
// time consuming work like:
System.Threading.Thread.Sleep(1000);
}
await T1;
}
当然lambda的主体和方法只是为了这个例子(正如我所说的,我需要稍后运行),但无论如何,await T1
我无法进入lambda!我错过了什么?我感到很愚蠢,因为我已经使用了async-await范例已经很多年了,我甚至没有想到这不会起作用!
答案 0 :(得分:4)
我认为可以在评论中回答,但最好提供更多信息。
await
表示“等待此任务完成,然后完成其余工作”。您的示例中的任务未启动。 await
不会为您启动它,因此整个方法只会停留在await
,直到您开始执行任务。
即使使用当前代码,如果您稍后执行T1.Start()
- 它将运行您的lambda并在完成后 - CreateAndAwaitAsync
返回的任务也将完成。
否则 - 在创建任务时启动任务(Task.Run
)或直接返回Task
而不使用任何异步\ await:
public Task CreateAndAwaitAsync()
{
T1 = new Task(() => {
// time consuming work like:
System.Threading.Thread.Sleep(1000);
}
// if you need to start it somewhere, do T1.Start();
return T1;
}
答案 1 :(得分:2)
像@Evk所说,你需要调用T1.Start()
public async Task CreateAndAwaitAsync()
{
T1 = new Task(() =>
{
// time consuming work like:
System.Threading.Thread.Sleep(1000);
});
T1.Start();
await T1;
}
答案 2 :(得分:1)
你没有开始这项任务。
示例:
public async Task DoSomething()
{
await Task.Run(() => SomeMethod());
}
答案 3 :(得分:0)
您只是创建了一个await
,但即使在此处使用Start()
,它也无法运行。尝试T1 = Task.Run(your => lambda)
,或者您可以指定$variableName = "res" + $i
New-Variable -Name $variableName -Value New-Object System.Windows.Forms.Label
然后等待它时它应该有用
答案 4 :(得分:0)
除非您正在进行CPU绑定工作,否则几乎不需要调用Task.Run,但可以使用async / await,如:
public async Task DelayMe()
{
await Task.Delay(1000);
await MoreAsyncThings();
}
Task T1 { get; set; }
public async Task CreateAndAwaitAsync()
{
T1 = DelayMe();
await T1;
}
更新
为了存储代码供以后执行,我建议简单地使用lambda,如:
Func<Task> SomeWorkFactory()
{
return async () =>
{
await AsyncStuff();
// More Stuff
};
}
var deferedWork = SomeWorkFactory();
// later somewhere else
await deferedWork();
所以基本上调用“SomeWorkFactory”创建工作包,但只调用Func执行它并返回一个等待的任务。
也许相关:
如果提供执行CPU绑定工作的方法(比如计算某些东西而不是等待回调),则不应该提供异步签名,而是将执行模式保留给调用者。主要是因为异步和并发是不同的概念。 Mads Torgersen在这里给出了一些见解:https://channel9.msdn.com/Events/TechEd/NorthAmerica/2014/DEV-B362并称之为“图书馆方法不应该谎言”(从第42分钟开始)