Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 返回任务而不是任务是否完全错误<;T>;?_C#_Async Await - Fatal编程技术网

C# 返回任务而不是任务是否完全错误<;T>;?

C# 返回任务而不是任务是否完全错误<;T>;?,c#,async-await,C#,Async Await,任务API感觉有点像一个失败的坑,因为我可以用它做的每一件事都比do多DON。但是我正在尝试更多地使用它,我对async void的整个问题感到困惑 我的问题发生在我的应用程序永远使用本地数据文件的地方,因为使用了快速同步调用。现在,一些远程源是一个选项,它们有足够的延迟,我将全部切换为异步 所以我有一个方法,可能看起来像这样: void InitializeData() { SomeProperty = _dataSource.Load(...); } 对于低摩擦,我想做的简单的事情

任务API感觉有点像一个失败的坑,因为我可以用它做的每一件事都比doDON。但是我正在尝试更多地使用它,我对
async void
的整个问题感到困惑

我的问题发生在我的应用程序永远使用本地数据文件的地方,因为使用了快速同步调用。现在,一些远程源是一个选项,它们有足够的延迟,我将全部切换为异步

所以我有一个方法,可能看起来像这样:

void InitializeData() {
    SomeProperty = _dataSource.Load(...);
}
对于低摩擦,我想做的简单的事情是:

Task InitializeDataAsync() {
    return Task.Run(() => {
        SomeProperty = _dataSource.Load(...);
    });
}
但是关于使用
async void
有多么糟糕的文章太多了,而且它们似乎随着返回任务的讨论而变得模糊不清。那么,我最好的选择是这样写:

Task<DataType> FetchDataAsync() {
    return _dataSource.LoadAsync(...);
}
Task FetchDataAsync(){
返回_dataSource.LoadAsync(…);
}
…然后追捕所有来电者并让他们服从

我觉得人们的论点是,
async void
是不好的,因为
async Task
的不同行为,以及使用
wait
时令人恐惧的未观察到的taskeexception。在这种情况下,我不太可能使用
wait
。或者,如果我使用wait,它总是会有一个try/catch围绕它,因为我们已经对未被观察到的taskeexception产生了偏执

因此:

  • “不使用
    async void
    ”是否与“不使用
    Task
    ”相同
  • 如果您不使用
    wait
    ,它会减轻这种情况吗
  • 如果您确实使用了
    wait
    ,是否总是用try/catch来包装它来缓解问题

  • 异步无效
    与返回任务不同。
    异步无效
    的问题是无法观察任务异常(除了全局异常处理程序),也无法等待任务完成(实际上,您不能使用
    wait
    异步void方法,因为没有任何东西可以
    wait
    ),这就是为什么应该避免它


    返回
    任务
    没有这些问题,如果你等待它,你知道它什么时候完成,你等待的地方会出现异常,因此返回
    任务
    是完全可以接受的。

    异步无效
    与返回
    任务
    不同。
    异步无效
    的问题就在那里无法观察任务异常(全局异常处理程序除外),也无法等待任务完成(实际上,您不能使用
    await
    异步void方法,因为没有任何东西可以
    await
    ),这就是为什么应该避免使用它


    返回
    任务
    没有这些问题,如果你等待它,你知道它什么时候完成,在等待的地方会出现异常,所以返回
    任务
    是完全可以接受的。

    看起来你只是困惑了。等待/异步API非常简单。唯一让人困惑的是理解。关于这一点,我将不作详细介绍,因为斯蒂芬·克利里的博客清楚地涵盖了这一点,但这里是重要的摘录:

    要重复我上一篇文章中的一句话,请使用Task.Run调用CPU绑定的方法(从GUI线程)。不要使用它只是为了“提供我的异步方法可以使用的东西”

    接下来

    对于低摩擦,我想做的简单的事情是:

    Task InitializeDataAsync() {
        return Task.Run(() => {
            SomeProperty = _dataSource.Load(...);
        });
    }
    
    这是一个很明显的例子,将同步代码卸载到一个异步包装器中,实际上没有任何好处

    但是有很多文章都提到使用async void是多么糟糕

    这显然是nota
    async void
    方法。这是一种非异步
    Task
    返回方法。以下是一种异步void方法:

    async void InitializeDataAsync() {
      await Task.Run(() => {
        SomeProperty = _dataSource.Load(...);
      });
    }
    
    他们似乎对返回任务的讨论模糊不清

    我没有读过任何模糊这一信息的东西。这很简单;如果你有一个
    异步
    方法,总是返回
    任务
    任务
    (以下说明除外)。使用这两种方法(
    任务
    任务
    )的区别纯粹是设计/架构

    那么,我最好的选择是这样写:

    Task<DataType> FetchDataAsync() {
        return _dataSource.LoadAsync(...);
    }
    
    这里的观点是最好的。这两种方法都有效,不要忘记异步/等待

    async Task<DataType> FetchDataAsync() {
      return await _dataSource.LoadAsync(...);
    }
    
    async Task FetchDataAsync() {
      _data = await _dataSource.LoadAsync(...);
    }
    
    异步任务FetchDataAsync(){ 返回wait_dataSource.LoadAsync(…); } 异步任务FetchDataAsync(){ _data=wait_dataSource.LoadAsync(…); } 我觉得人们的论点是async void是不好的,因为async任务的不同行为以及使用Wait时令人恐惧的UnobservedTaskeException

    :

    摘录:

    异步void方法具有不同的错误处理语义。当从异步任务或异步任务方法抛出异常时,将捕获该异常并将其放置在任务对象上。对于异步void方法,没有任务对象,因此从异步void方法抛出的任何异常都将直接在SynchronizationContext上引发在异步void方法启动时处于活动状态

    所以

    或者,如果我使用wait,它总是会有一个try/catch围绕它,因为我们已经对未被观察到的taskeexception产生了偏执

    这意味着您无法通过try/catch绕过异步void捕获异常。这是一个巨大的问题

    “不使用异步void”是否与“不使用任务”相同

    这是苹果和橙子。是的:不要使用
    async void
    ,除非您将它们用于

    不要使用任务,除非它们是CPU绑定的,或者您正在使用框架调用(或者您已经正确包装了自己使用的方法)

    如果您不使用wait,它会减轻这种影响吗

    希望到现在为止,您已经了解wait/async不同于任务,您要做的是编写一个