简体   繁体   English

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

[英]async await execution order - code only actually works when stepping through/debugging

I'm hoping there is a simple answer here, and this is probably due to my misunderstanding of asynchronous operations... 我希望这里有一个简单的答案,这可能是由于我对异步操作的误解...

I have a method that can be started manually or can autostart when the program loads. 我有一种方法可以手动启动,也可以在程序加载时自动启动。 The async method works perfectly when invoked manually (on button press). 当手动调用(按下按钮)时,async方法工作完美。 However, when autoloaded the method just seems to skip the main "await" part of the method without performing any work, and skips straight to the end. 但是,当自动加载该方法时,似乎只是跳过该方法的主要“ await”部分而不执行任何工作,而是直接跳到最后。

The whole process starts in this method: 整个过程从以下方法开始:

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.");
            }
        });    
    }
}

If _config.AutoStart is true, the BatchTransfer method doesn't seem to do anything, instead the program skips straight to the CompleteBatch() method. 如果_config.AutoStart为true,则BatchTransfer方法似乎不执行任何操作,而是直接跳至CompleteBatch()方法。 If invoked manually everything works as expected. 如果手动调用,一切都会按预期进行。

The strange thing is, if I set a breakpoint on await BatchTransfer(batchSize) in the autostarted method, I can step through the code and the batch transfers take place. 奇怪的是,如果我在自动启动方法的await BatchTransfer(batchSize)上设置了一个断点,则可以单步执行代码,然后进行批量传输。 So when debugging it works, when not debugging it doesn't. 因此,当调试时它起作用,而当不调试时就不起作用。 Please help! 请帮忙!

It is because - 这是因为 -

Task.Factory.StartNew(async () =>
    {
        await BatchTransfer(batchSize);
        CompleteBatch();
    });

You are waiting for the inner task to complete with await but Task.Factory.StartNew(async () => itself is an asynchronous task and is not awaited. You should also wait for Task.Factory.StartNew(async () => like this - 您正在等待内部任务await完成,但Task.Factory.StartNew(async () =>本身是异步任务且未等待。您还应等待Task.Factory.StartNew(async () =>这个 -

await Task.Factory.StartNew(async () =>

When you are debugging, the separate thread that is calling inner task is held and you can see the execution but when running normally the background is still working, but you cannot see it since you didn't wait for the Task.Factory.StartNew(async () => . 在调试时,将保留调用内部任务的单独线程,您可以看到执行情况,但是在正常运行时,后台仍在工作,但由于没有等待Task.Factory.StartNew(async () =>

If you check the thread pool and thread id, I am sure you will see that they are different when debugging. 如果您检查线程池和线程ID,我相信您会在调试时看到它们是不同的。

This blog might help you understand the situation - http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx 该博客可能会帮助您了解情况-http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx

In order to use await you have to make your method async and call it without Task.Factory.StartNew . 为了使用await您必须使方法async并在没有Task.Factory.StartNew情况下调用它。 One more thing, instead of void make return type as Task of your method because void async are fire and forget. 还有一件事,而不是使void作为方法的Task返回类型,因为void异步会引起火灾并忘记。 You will not able to track them. 您将无法跟踪它们。

private async Task StartBatch()
{
    await BatchTransfer(batchSize);
    CompleteBatch();
}

Check this link. 检查此链接。 It have very basic demonstration of async and it is very helpful in understanding how asynchrony works. 它具有非常基本的async演示,对于理解asynchrony工作方式非常有帮助。 Six Essential Tips For Async - Introduction . 异步的六个基本技巧-简介 It includes six tips which are very essential. 它包括六个非常重要的技巧。 I recommend you go through all of them but to understand current question situation you can go through Tip 1 whose title is Async void is for top-level event-handlers only . 我建议您仔细阅读所有内容,但要了解当前的问题情况,可以阅读技巧1,其标题为Async void仅适用于顶级事件处理程序

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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