是否等待新Task(async()=>实际上暂停执行直到完成? [英] Does await new Task(async () => Actually halt execution until finished?

查看:273
本文介绍了是否等待新Task(async()=>实际上暂停执行直到完成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我不太了解c#中的await命令.我以为使用await将允许方法继续处理,并且将在单独的线程中工作并在完成后返回值,但是,我有以下代码:

I guess I'm not really understanding the await command in c#. I thought that using await would allow a method to continue processing and would would work in a separate thread and return a value once it completed however, I have the following code:

public async Task<DatabaseActionResult> BackupToAzureAsync(DatabaseSchedule schedule)
{
    try
    {       
        foreach (var o in myObjects)
        {
                await new Task(async () =>
                {
                    try
                    {
                        //Do some stuff.
                    }
                    catch (Exception e)
                    {
                        throw; //Should this throw the exception to the functions Try/Catch block so it can log it to the event viewer?
                    }
                }
            }   
        }
    catch (Exception e)
    {
        //Log exception to event viewer and return a DatabaseActionResult object
    }
}

但是,foreach()执行,等待任务完成,然后仅在完成后才继续执行下一个.如果删除await语句,则它将同时为每个循环迭代运行任务,但Try/Catch块不会将异常抛出堆栈.相反,它只是完全停止了服务,就好像它是服务未处理的异常一样.

However, the foreach() executes, waits for the task to complete, and then only after completion, continues to the next. If I remove the await statement, then it runs the task for every loop iteration simultaneously but the Try/Catch block doesn't throw the exception up the stack. Instead it just stop the service entirely as if it were a service unhandled exception.

如何让新的任务为每个for/each循环运行一次而不等待上一个任务完成,或者如何让try/catch块将异常抛出堆栈以使其能够获取在方法的try/catch块中捕获并处理?

How can I either get the new task to run once for each for/each loop without waiting for the previous one to complete, or how can I get the try/catch block to throw the exception up the stack so it can get caught and processed in the method's try/catch block?

谢谢!

跟进:

这项工作还能保持Try/Catch堆栈吗?

Would this work and still maintain the Try/Catch stack?

foreach (var t in tables)
{
    try
    {
        var tableTasks = new List<Task>
        {
            new Task(async () =>
                {
                    try
                    {
                        //Do stuff
                    }
                    catch (DataError e)
                    {
                        throw e;
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                }
            )
        };
    }
    catch (Exception e)
    {
        return new DatabaseActionResult();
    }
}

推荐答案

我想我不太了解c#中的await命令.

I guess I'm not really understanding the await command in c#.

是正确的.在提出问题之前 做一些研究.有很多StackOverflow问题,文章,视频,教程和书籍来解释其工作原理.

That's correct. Do some research before you ask a question. There are many StackOverflow questions, articles, videos, tutorial and books that explain how this works.

我认为使用await将允许方法继续处理,并且将在单独的线程中工作并在完成后返回值

I thought that using await would allow a method to continue processing and would would work in a separate thread and return a value once it completed

那是100%绝对错误,所以现在就不要再想所有这些了.<​​/p>

That is 100% absolutely wrong, so stop thinking all of that right now.

但是,foreach()执行,等待任务完成,

However, the foreach() executes, waits for the task to complete,

异步等待-等待-等待任务完成.这就是为什么它叫做等待"的原因.

An asynchronous wait -- await -- waits for a task to complete. That's why its called "await".

这是异步,因为如果任务未完成,则 await返回给调用方并在该线程上执行其他工作,直到任务完成为止,此时计划执行等待之后的工作.

It is asynchronous because if the task is not complete then await returns to the caller and does other work on this thread until the task is complete, at which time the work that follows the await is scheduled to execute.

确保您了解 await是执行任务的操作员.这不是通话中的通话惯例.任何等待类型的表达式都可以等待;不要陷入相信 await进行异步通话的陷阱.调用的方法已经已经异步了;返回的任务就是等待的事情.

Make sure you understand that await is an operator on tasks. It is not a calling convention on calls. Any expression of awaitable type can be awaited; don't fall into the trap of believing that await makes a call asynchronous. The called method is already asynchronous; the task that is returned is the thing that is awaited.

如何让新任务针对每个for/each循环运行一次,而不必等待上一个任务完成

How can I either get the new task to run once for each for/each loop without waiting for the previous one to complete

不要等待任务. 等待表示在完成此任务之前,我无法继续."

如果您所需的工作流程是每个对象创建一个任务并异步等待所有任务完成",则为await Task.WhenAll(tasks).因此,创建任务序列-使用循环创建列表,或使用Select创建序列-然后立即等待所有任务.

If your desired workflow is "create one task per object and asynchronously wait for all of them to finish", that's await Task.WhenAll(tasks). So create a sequence of tasks -- either using your loop to build up a list, or a Select to create a sequence -- and then await all of them at once.

请注意,在WhenAll情况下的异常处理有点不寻常. 在编写代码之前,请仔细阅读文档并理解它.

Note that exception handling in a WhenAll situation is a little bit unusual. Read the documentation carefully and understand it before you write the code.

这篇关于是否等待新Task(async()=&gt;实际上暂停执行直到完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆