[英]Await new Task<T>( ... ) : Task does not run?
在这里提出的问题的延续:
在上述问题中,我有以下函数返回 Task 类型的对象(用于增量测试):
private static Task<object> GetInstance( ) {
return new Task<object>( (Func<Task<object>>)(async ( ) => {
await SimpleMessage.ShowAsync( "TEST" );
return new object( );
} ) );
}
当我调用await GetInstance( );
,该函数被调用(并且我假设该任务被返回,因为没有抛出异常)但是任务只是坐在那里。
我只能猜测我当时做错了。
我不希望此函数返回已在运行的任务(即IMPERATIVE )。
如何异步运行此函数返回的任务?
创建一个已经开始的任务
尝试创建这样的任务:
Task.Factory.StartNew<object>((Func<Task<object>>) ...);
在不启动的情况下创建任务
如果您不希望任务开始,只需像您使用的那样使用new Task<object>(...)
,但是您需要在等待它之前对该任务调用Start()
方法!
我的推荐
只需创建一个返回匿名函数的方法,如下所示:
private static Func<object> GetFunction( ) {
return (Func<object>)(( ) => {
SimpleMessage.Show( "TEST" );
return new object( );
} );
}
然后获取它并在需要时在新Task
运行它(另请注意,我从 lambda 表达式中删除了async/await
,因为您已经将其放入任务中):
Task.Factory.StartNew<object>(GetFunction());
这样做的一个优点是您也可以在不将其放入Task
情况下调用它:
GetFunction()();
您永远不应该使用Task
构造函数(或Task.Start
)。
我不希望此函数返回已在运行的任务(即 IMPERATIVE )。
那么,您想返回一些在您调用之前不会执行的代码吗? 那是一个委托,而不是一个Task
。
private static Func<Task<object>> GetInstance()
{
return async () =>
{
await SimpleMessage.ShowAsync("TEST");
return new object();
};
}
当您准备好执行它时,就像任何其他委托一样调用它。 请注意,它返回一个Task
,因此您可以await
结果:
var func = GetInstance();
// Delegate has not started executing yet
var task = func();
// Delegate has started executing
var result = await task;
// Delegate is done
你被一个糟糕的设计困住了。 在这些限制下,我会尝试为您做一些事情。
延迟启动任务的唯一方法是使用Task.Start
方法。 (您也可以使用RunSynchronously
但这并没有真正利用任何任务功能。此时任务变成了一个无线程的惰性对象。
所以使用Task.Start
方法。
await
不启动任务。 它等待已经运行的任务。 因此await new Task(() => { })
总是永远冻结。
这里的另一个问题:
return new Task<object>( (Func<Task<object>>)(async ( ) => {
await SimpleMessage.ShowAsync( "TEST" );
return new object( );
} ) );
当您开始该任务时,它几乎会立即完成并且Task.Result
将保存另一个任务 - 由异步 lambda 返回的任务。 我怀疑这就是你想要的。 很难做到这一点,我不知道你需要什么。
这闻起来像 XY 问题。 你能详细说明你想完成什么吗? 感觉就像你给了自己不必要的限制。
好的,我想我已经弄清楚了。 请检查此代码:
class Program
{
public static void Main(string[] args)
{
// Only RUN the task as needed. FooGet
// still allows you to generalize your task.
Task.Run(() =>
{
dynamic value = FooGet();
value.RunSynchronously();
Console.WriteLine(value.Result.Result.ToString());
});
while (true) Thread.Sleep(100);
}
private static Task<object> FooGet()
{
var task = new Task<object>(() => {
return asyncBar();
});
return task;
}
private async static Task<object> asyncBar()
{
// do work!
return "Hello, world!";
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.