[英]async await execution order - code only actually works when stepping through/debugging
我希望这里有一个简单的答案,这可能是由于我对异步操作的误解...
我有一种方法可以手动启动,也可以在程序加载时自动启动。 当手动调用(按下按钮)时,async方法工作完美。 但是,当自动加载该方法时,似乎只是跳过该方法的主要“ await”部分而不执行任何工作,而是直接跳到最后。
整个过程从以下方法开始:
private void StartBatch()
{
var batchSize = (int)BatchSizeSlider.Value;
if (_config.AutoStart)
{
ExecutionLogAddItem(string.Format("Auto batch processing started (batch size: {0})", batchSize.ToString()));
Task.Factory.StartNew(async () =>
{
await BatchTransfer(batchSize);
CompleteBatch();
});
}
else
{
var start = ConfirmStartBatch();
var doBatch = start.ContinueWith(async (continuation) =>
{
//start task
if (start.Result == true)
{
ExecutionLogAddItem("Batch processing started.");
ExecutionLogAddItem(string.Format("Batch size set at {0}", batchSize.ToString()));
await BatchTransfer(batchSize).ContinueWith((x) => CompleteBatch());
}
else
{
ExecutionLogAddItem("Batch processing aborted.");
}
});
}
}
如果_config.AutoStart
为true,则BatchTransfer方法似乎不执行任何操作,而是直接跳至CompleteBatch()
方法。 如果手动调用,一切都会按预期进行。
奇怪的是,如果我在自动启动方法的await BatchTransfer(batchSize)
上设置了一个断点,则可以单步执行代码,然后进行批量传输。 因此,当调试时它起作用,而当不调试时就不起作用。 请帮忙!
这是因为 -
Task.Factory.StartNew(async () =>
{
await BatchTransfer(batchSize);
CompleteBatch();
});
您正在等待内部任务await
完成,但Task.Factory.StartNew(async () =>
本身是异步任务且未等待。您还应等待Task.Factory.StartNew(async () =>
这个 -
await Task.Factory.StartNew(async () =>
在调试时,将保留调用内部任务的单独线程,您可以看到执行情况,但是在正常运行时,后台仍在工作,但由于没有等待Task.Factory.StartNew(async () =>
。
如果您检查线程池和线程ID,我相信您会在调试时看到它们是不同的。
该博客可能会帮助您了解情况-http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx
为了使用await
您必须使方法async
并在没有Task.Factory.StartNew
情况下调用它。 还有一件事,而不是使void
作为方法的Task
返回类型,因为void异步会引起火灾并忘记。 您将无法跟踪它们。
private async Task StartBatch()
{
await BatchTransfer(batchSize);
CompleteBatch();
}
检查此链接。 它具有非常基本的async
演示,对于理解asynchrony
工作方式非常有帮助。 异步的六个基本技巧-简介 。 它包括六个非常重要的技巧。 我建议您仔细阅读所有内容,但要了解当前的问题情况,可以阅读技巧1,其标题为Async void仅适用于顶级事件处理程序 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.