[英]What causes a Task to complete?
我试图找出如何使用WhenAll
让两种方法同时运行,而一旦他们都完成,收集结果,而不使用阻断.Result
我有这个小的控制台应用程序测试:
using System.Diagnostics;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
public static void Main(string[] args)
{
var run = TaskRunner();
Debug.WriteLine(run);
if (run.IsCompleted)
{
Debug.WriteLine("this worked!");
} else
{
Debug.WriteLine("this failed!");
}
}
public static async Task<string> TaskRunner()
{
var taskOne = OneAsync();
var taskTwo = TwoAsync();
var tasks = await Task.WhenAll(taskOne, taskTwo);
var retval = tasks[0] + tasks[1];
return retval;
}
public static Task<string> OneAsync()
{
return Task.Run(() =>
{
return "test1";
});
}
public static Task<string> TwoAsync()
{
return Task.Run(() =>
{
return "test2";
});
}
}
}
当前打印this worked!
作品this worked!
到我的输出窗口...但是,如果我注释掉Debug.WriteLine(run);
它打印this failed!
...为什么仅通过登录到输出窗口即可完成任务?
我试图理解一段复杂的代码中的一个巨大问题,而这个小测试是我的MCVE,希望可以对幕后发生的事情有所了解。
这只是偶然的机会。 开始任务的方式是使用Task.Run
。 这实质上创建了一个新线程,在该线程上执行(同步)动作。 它返回一个任务以完成该线程。
因此, OneAsync
和TwoAsync
将各自产生一个新线程,然后立即返回一个字符串。 这将很快发生,但是创建那些线程仍然有一些开销,这意味着它不会是瞬时的 。
然后, TaskRunner
调用这两个方法(生成线程),然后异步等待两个线程完成。 由于线程不是立即完成的,因此TaskRunner
方法也不会立即完成。
现在,您主要是在启动异步TaskRunner
,我们认为这将花费“很短的时间” 。 你不等待任务,所以执行立即继续。 执行Debug.WriteLine
来打印某些内容(可能要打印的是相关任务,这实际上并不重要), 然后您正在检查任务的状态。
由于打印内容相对较慢(与其他操作相比),这可能是任务最终完成的原因。 而且,当您删除打印件时, if
太快了,无法完成任务。
正如您可能注意到的那样,与异步任务一起工作似乎不是一个好主意。 因此,当您依赖任务的结果时,应该始终等待它。
// note the *async* here; async main methods are supported with C# 7.1
public static async void Main(string[] args)
{
var run = TaskRunner();
// await the task
await run;
if (run.IsCompleted)
{
Debug.WriteLine("this worked!");
}
else
{
Debug.WriteLine("this failed!");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.