繁体   English   中英

异步等待执行顺序-代码仅在逐步执行/调试时才有效

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM