RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1420229
Accepted
Potion
Potion
Asked:2022-08-14 22:25:22 +0000 UTC2022-08-14 22:25:22 +0000 UTC 2022-08-14 22:25:22 +0000 UTC

从同步上下文过渡到异步 - 哪个更好 - 任务还是无效?

  • 772

从同步上下文转移到异步上下文的最佳方法是什么?如果父方法不知道如何等待任何东西,但你想异步运行一些东西,那么最好的使用方法是什么?似乎他们写道 async void 是一种不好的做法,因为它没有控制任务,启动它 - 并且不清楚接下来会发生什么。但是从同步方法启动任务时结果不一样吗?他没有等她,发射——然后忘记了。

一般来说,任务是从同步方法中启动一个异步方法,如何最正确地做到这一点?

class Hello
{         
    static void Main(string[] args)
    {
        SomeVoidMethod();
        SomeTaskMethod();
    }

    async void SomeVoidMethod()
    {

    }

    async Task SomeTaskMethod()
    {
        return Task.CompletedTask;
    }
}
c# async-await
  • 1 1 个回答
  • 63 Views

1 个回答

  • Voted
  1. Best Answer
    aepot
    2022-08-15T00:21:53Z2022-08-15T00:21:53Z

    在这种特殊情况下,没关系,因为您不使用await,并且Task根本不编译的那个,并且 main 不会编译,您至少应该在将代码插入问题之前检查代码.

    并且显示的两种方法都是同步的。不会async使方法异步,但是await.

    async void- 这是一种“一劳永逸”的方法,也就是说,你启动一个异步操作,然后你不会以任何方式跟踪它,如果在那里抛出异常,那么它充其量会随着操作的某个地方而死线程池,最坏的情况是它会使上下文同步崩溃,你会想知道到底发生了什么以及如何捕获这个异常。

    因此,只有await且只有Task。

    static async Task Main(string[] args)
    {
        await SomeTaskMethod();
    }
    
    static async Task SomeTaskMethod()
    {
        await Task.Delay(100);
        Console.WriteLine("Метод закончил работу.");
    }
    

    从主目录中删除await它,您将看不到控制台的输出。不可预测的代码行为总是不好的。

    如果您需要“启动并忘记” async void,那么您绝对应该处理异常并考虑到该方法将在您无法控制的时间完成工作。也就是说,应用程序至少应该比这种方法运行更长的时间。

    static void Main(string[] args)
    {
        SomeVoidMethod();
        Console.ReadKey();
    }
    
    static async void SomeVoidMethod()
    {
        await Task.Delay(100);
        Console.WriteLine("Метод закончил работу.");
    }
    

    从主目录中删除Console.ReadKey()它,您将看不到控制台的输出。代码的不可预测的行为 - 好吧,你明白了。

    现在像这样

    // ПЛОХОЙ КОД
    static void Main(string[] args)
    {
        try
        {
            SomeVoidMethod();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.ReadKey();
    }
    
    static async void SomeVoidMethod()
    {
        await Task.Delay(100);
        throw new InvalidOperationException("Метод дал сбой.");
    }
    

    在执行可能重要的代码期间,此方法会使您的应用程序崩溃。突然间,main 将某些内容写入磁盘,例如,保存用户数据。对于 main 来说,一切都很好,但是方法中抛出的异常async void会丢弃整个应用程序,即使你将它包装在 . 中try-catch,它也无济于事。尝试在不更改方法本身的代码的情况下捕获异常 - 你不会成功。顺便说一句,如果在这个例子中你void将它替换为Task,那么异常将陷入深渊,你根本看不到它,它根本不起作用,你不会知道它并寻找了很长时间,找了半天原因。

    因此,在方法中捕获异常async void是一个强制性的过程。

    static void Main(string[] args)
    {
        SomeVoidMethod();
        Console.ReadKey();
    }
    
    static async void SomeVoidMethod()
    {
        try
        {
            await Task.Delay(100);
            throw new InvalidOperationException("Метод дал сбой.");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
    

    如果要捕获方法外的异常,请使用async Taskand await。

    关于

    从同步方法运行到异步

    然后不要在类构造函数中编写代码,而是在异步方法中编写代码。

    var helper = new HelperClass();
    await helper.StartAsync();
    

    而且您不必从同步方法运行异步方法。对于各种 winforms 中的事件处理程序async void,以及如何使用它 - 我在上面展示了。

    读:

    • .NET Framework 4.8 上 WPF 下的 C# 中的线程、任务、异步、等待
    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5