C# 异步/等待。打电话忘记,不要等待。和长时间运行的过程

C# 异步/等待。打电话忘记,不要等待。和长时间运行的过程,c#,asynchronous,async-await,C#,Asynchronous,Async Await,我试图利用新的(相对而言)基于任务的C#异步/等待特性。我看了几个例子,大致了解了优势。 如果有人与我/我们分享以下两个主题的一些线索或代码,我将不胜感激: 我过去常常在“过程”中多次写入一些日志/跟踪信息(如写入TXT文件日志或将某些状态转储到数据库中等)。我觉得异步执行这些调用(调用并忘记,无需等待)将非常有效。但我学到的是,每个异步任务都必须有一个等待,才能真正异步。 那么,在“main method/function”过程中多次调用同一个方法(使用不同的参数值,如message…)的解决

我试图利用新的(相对而言)基于任务的C#异步/等待特性。我看了几个例子,大致了解了优势。 如果有人与我/我们分享以下两个主题的一些线索或代码,我将不胜感激:


  • 我过去常常在“过程”中多次写入一些日志/跟踪信息(如写入TXT文件日志或将某些状态转储到数据库中等)。我觉得异步执行这些调用(调用并忘记,无需等待)将非常有效。但我学到的是,每个异步任务都必须有一个等待,才能真正异步。 那么,在“main method/function”过程中多次调用同一个方法(使用不同的参数值,如message…)的解决方案是什么,而不是像“wait”那样等待每次调用

  • 我有一个相当复杂的[processA()](class.method),它在windows服务中“main”类的循环中被调用,以处理“next doc”(数千次)(长时间运行的进程)。我想将这个[processA()]放在一个任务中,并并行使用4-8个任务来调用[processA()]

  • 任何线索、有用的链接或代码示例都将受到真诚的感谢。 提前谢谢

    我觉得异步调用(调用并忘记,无需等待)会非常有效

    fire and forget的问题是,您不知道操作是否失败。对于大多数代码来说,这是不可接受的

    许多日志框架同步写入内存存储,然后定期刷新到磁盘/db。这在速度和日志可靠性之间进行了很好的权衡

    我想将这个[processA()]放在一个任务中,并并行使用4-8个任务来调用[processA()]

    听起来你把异步和并行处理混淆了。如果你想使用并行处理,那么就使用
    parallel.ForEach
    或类似的东西;如果要使用异步,那么第一步是使
    processA
    异步,然后使用
    wait Task.whalll
    完成所有任务

    我觉得异步调用(调用并忘记,无需等待)会非常有效

    fire and forget的问题是,您不知道操作是否失败。对于大多数代码来说,这是不可接受的

    许多日志框架同步写入内存存储,然后定期刷新到磁盘/db。这在速度和日志可靠性之间进行了很好的权衡

    我想将这个[processA()]放在一个任务中,并并行使用4-8个任务来调用[processA()]


    听起来你把异步和并行处理混淆了。如果你想使用并行处理,那么就使用
    parallel.ForEach
    或类似的东西;如果您想使用异步,那么第一步是使
    processA
    异步,然后使用
    wait Task。当所有的任务都要完成时。

    “必须有一个wait,才能真正异步”-这是一个误解。方法可以是异步的,不管您是否等待它。方法代码本身决定了异步的本质。不等待该方法会禁止您捕获异常,因此如果调用失败,它可能会导致整个应用程序随之停止(web应用除外)。
    Enumerable.Range(0,threadCount)。选择(tId=>Task.Start(()=>processA())
    .Task.Start通常不受欢迎,但它可以强制使同步方法异步兼容。这是一种虚假的异步,所以要小心。这是有防御性的。我认为您需要记住,即使任务需要等待,也不必一开始就等待。您可以使用Task.Run或Task.Factor创建所有任务y、 StartNew将启动它们。然后您可以等待所有它们。您可能还想查看Parallel.For loop。@Machinarius说到您的观点,我认为重要的是要注意TaskScheduler负责工作的运行位置和任务。Start仅使用CurrentSyncionationContext。即使使用Task.Factor,也可以实现这一点y、 StartNew.“必须有一个等待,才是真正的异步”-这是一个误解。一个方法可以是异步的,不管你是否等待它。是方法代码本身决定了异步的性质。不等待方法会阻止你捕获异常,所以如果调用失败,它可能会导致整个应用程序崩溃(为web应用保存)。
    Enumerable.Range(0,threadCount)。选择(tId=>Task.Start(()=>processA())
    .Task.Start通常不受欢迎,但它可以强制使同步方法异步兼容。这是一种虚假的异步,所以要小心。这是有防御性的。我认为您需要记住,即使任务需要等待,也不必一开始就等待。您可以使用Task.Run或Task.Factor创建所有任务y、 StartNew将启动它们。然后您可以等待所有它们。您可能还想查看Parallel.For loop。@Machinarius说到您的观点,我认为重要的是要注意TaskScheduler负责工作的运行位置和任务。Start仅使用CurrentSyncionationContext。即使使用Task.Factor,也可以实现这一点y、 还有第一点——如果我错了,请纠正我——异步不可能真正做到一劳永逸,因为它就像一个回飞棒——最终它会回到你的身边(或者至少是一些)异步工作完成时,线程将被中断。如果是真正的F&F,您必须排队并处理进程外的事务。
    async void
    总是先发后忘。
    async Task
    没有等待的也是先发后忘。@MatthewWhited:
    async void
    有一些有趣的异常处理语义-我喜欢将其称为“启动并崩溃”。
    异步任务
    和丢弃的任务是真正的启动并遗忘。@St