C# 异步/等待vs任务。在C中运行#

C# 异步/等待vs任务。在C中运行#,c#,.net,multithreading,asynchronous,C#,.net,Multithreading,Asynchronous,我刚刚接触过这个异步的世界。 请容忍我缺乏知识 据说当一种方法遇到等待。。。“它告诉等待者在完成时运行方法的其余部分,然后从异步方法返回。” 我没有得到这个部分。 那么,这是否意味着该方法仍在同步运行,等待等待返回,然后继续执行该方法的其余部分? 如果没有,请解释为什么需要Task.Run在后台或以触发并忘记方式运行方法。我仍然可以通过等待来实现,对吗?i、 e. 该方法继续执行其余语句,而不等待等待返回。 我希望这类似于后台运行方法。或者不是吗?我很困惑 如果一个方法标记为async和awai

我刚刚接触过这个异步的世界。
请容忍我缺乏知识

  • 据说当一种方法遇到等待。。。“它告诉等待者在完成时运行方法的其余部分,然后从异步方法返回。
    我没有得到这个部分。
    那么,这是否意味着该方法仍在同步运行,等待等待返回,然后继续执行该方法的其余部分?
    如果没有,请解释为什么需要
    Task.Run
    在后台或以触发并忘记方式运行方法。我仍然可以通过等待来实现,对吗?i、 e.
    该方法继续执行其余语句,而不等待等待返回。
    我希望这类似于后台运行方法。或者不是吗?我很困惑

  • 如果一个方法标记为async和await,而该方法又在另一个层中异步调用另一个方法,该层也标记为async和await..
    那么,第一个标记为async并从单独的方法等待的方法的调用名称ABC应该是什么样子的?
    我不想将该方法注释为async/await。所以

    Task.Run(() => DoWork());
    
    从ABC()可以,但不标记为异步/等待?
    还是违反了异步原则

  • 以下是我正在努力实现的目标

       public IList<CreateCaseOutput> ABC(CreateCaseInput CreateCaseInput,SaveCaseSearchInput SaveCaseSearchInput)
        {
            CaseSQL.getABCParameters(CreateCaseInput, RequestType, out strSPQuery, out listParam);
            var AcctLst = rep.ExecuteStoredProcedure<CreateCaseOutput>(strSPQuery, listParam).ToList();
    
            if (!string.IsNullOrEmpty(AcctLst.ElementAt(0).o_case_seq.ToString()))
            {
                Task.Run(async () =>
                {
                    await DEF(SaveCaseSearchInput, AcctLst.ElementAt(0).o_case_seq);
                }).ConfigureAwait(false);              
            }
            console.writeLine("After Async called");
            return AcctLst;
        }
    
        public async Task<SaveCaseSearchOutput>> DEF(SaveCaseSearchInput SaveCaseSearchInput,Int64? case_key)
        {
    
                CaseSQL.getDEFParameters(SaveCaseSearchInput, case_key, out strSPQuery, out listParam);
                var AcctLst = await rep.ExecuteStoredProcedureAsync<SaveCaseSearchOutput>(strSPQuery, listParam);
                return AcctLst;
        }
    
    而不是

     Task.Run(async () =>
                    {
                        await DEF(SaveCaseSearchInput, AcctLst.ElementAt(0).o_case_seq);
                    }).ConfigureAwait(false);              
                }
                return AcctLst;
    
    然后,此代码在调试器中同步运行

    我做错什么了吗?

    '。。。“它告诉等待者在完成时运行方法的其余部分,然后从异步方法返回。”'

    假设您有一个调用方法B的方法a。方法B的声明中有“async”关键字。在方法B中,对LongMethod有一个耗时的调用,它最终返回一个字符串

    这里我们想要的是方法A不必等待方法B的LongMethod完成。因此,我们在方法B中写道:

    string newVariable=wait Task.Run(()=>LongMethod())

    如果LongMethod本身也是异步的,那么LongMethod只能返回void、非泛型任务或泛型任务。因此,我们必须将LongMethod声明中的返回类型更改为
    Task

    回到我们的故事,LongMethod任务已经开始。。。此时,方法A从调用方法B后的下一行代码恢复,方法B继续等待LongMethod完成,因此现在有两个线程正在运行。最终,LongMethod完成,方法B运行到最后,同时方法A继续运行,甚至可能已经完成运行

    我希望这能让您了解异步/等待和任务之间的关系

    现在回答问题2:

    我认为您的问题基本上是问我的示例中的方法A是否需要标记为“async”,因为它调用标记为“async”的方法,而不是。另外请注意,ABC()只需要

    DoWork()
    Task.Run(()=>DoWork())

    然后,ABC将停止运行,直到DoWork方法到达“await”语句

    如果DoWork只需要作为自己的任务运行,而您根本不希望ABC()停止,那么就这样做吧

    Task.Run(()=>DoWork())

    在这种情况下,将DoWork标记为async没有任何好处,因为在DoWork中没有任何等待语句

    我希望这能有所帮助,如果我误解了你的问题,请原谅

    那么,这是否意味着该方法仍然保持同步运行,等待等待的返回,然后继续执行该方法的其余部分

    不是。等待有一个“回调”机制。因此,该方法只是将其自身注册到等待中。当等待完成时,它将执行回调,其中包括
    async
    方法的延续

    同时,
    async
    方法返回一个未完成的任务

    如果没有,请解释为什么需要Task.Run在后台或以fire and forget方式运行方法

    如果要在后台线程上运行,请使用
    Task.run
    <代码>任务。运行
    仅将工作安排到线程池

    我仍然可以通过等待来实现,对吗?即 该方法继续执行其余语句,而不等待wait返回。 我希望这类似于后台运行方法。或者不是吗?我很困惑

    好吧,你可以通过不等待来“忘记”任务:

    MyMethod()
    {
      SomeMethodAsync(); // Note: no await; we just ignore the task.
    }
    
    不过,你几乎从来都不想做“开火然后忘记”。很容易>90%的人要求它,这实际上是一个设计错误

    我不想将该方法注释为async/await。。。还是违反了异步原则

    那是违反原则的。如果您仔细想想,阻塞异步代码是没有意义的。您希望经历使方法异步(意味着它不阻塞线程)的麻烦,然后在其上阻塞线程吗?为什么呢?有时在实践中,代码在转换到异步代码时会暂时处于这种状态,但这是一个棘手的问题


    有关更多信息,请参阅我在上的文章,特别是“一路异步”。

    来自您在评论中所说的内容(我假设您需要ABC中的结果)

    你只需要写

    Task t=Task.Run(()=>DEF(SaveCaseSearchInput,AcctLst.ElementAt(0.o_case_seq))

    在ABC中,而不是当前任务。运行调用

    然后在ABC中的行中,当您需要写入结果时

    t.Wait()
    SaveCaseSearchOutput g=t.结果


    DEF必须保持异步,但您可以删除DEF中的WAIT语句。

    我想解释一下,但它已经很简单了,看看这是否有助于解决问题
    MyMethod()
    {
      SomeMethodAsync(); // Note: no await; we just ignore the task.
    }