加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 触发并忘记异步任务方法有时不会调用

发布时间:2020-12-15 04:03:16 所属栏目:百科 来源:网络整理
导读:我有一个异步方法: public async Task DoSomethingAsync(){ ... await ... await ... .... return await SaveAsync();} 在大多数时候,我通过以下方式调用此方法: await DoSomethingAsync() 此调用按预期工作.但在某个地方,我需要将此方法称为火,并忘记: p
我有一个异步方法:
public async Task DoSomethingAsync(){
    ...
    await ...
    await ...
    ....
    return await SaveAsync();
}

在大多数时候,我通过以下方式调用此方法:

await DoSomethingAsync()

此调用按预期工作.但在某个地方,我需要将此方法称为火,并忘记:

public void OtherMethod()
{
    ...
    DoSomethingAsync(); //fire and forget here
}

在这种情况下,有时Task DoSomethingAsync()会运行并完成,但有时任务永远不会被调用(或在DoSomethingAsync()中调用一些等待但永远不会完成最后一次等待SaveAsync();).

我正在尝试通过以下代码确保以火灾和忘记方式调用任务:

public void OtherMethod()
{
    ...
    Task.Factory.StartNew(() =>
    {
        await DoSomethingAsync();
    }); //fire and forget again here
}

但是,这不符合预期.所以我的问题是:

>如何在没有等待的情况下调用DoSomethingAsync()将始终运行并完成? (我不关心AppDomain重启/崩溃的情况)
>如果我删除DoSomethingAsync()中的所有异步/等待代码并用.ContinueWith()替换await,那么将调用Task DoSomethingAsync()(方法声明中没有异步)的调用并确保完成(忽略大小写AppDomain重启) /崩溃),如果是的话,从通话中退出多长时间(我不认为如果在10分钟后调用任务我会很高兴)?

解决方法

等待应该工作正常,所以这里可能还有其他东西正在等待你的一个或多个方法.有几种可能性:

>你的某个方法中有某个死锁,阻止它完成并阻止等待恢复.
>由于某种原因,所有线程池线程都阻塞,阻止挂起的任务运行.
>您正在同步上下文中运行异步方法,并且正在阻止上下文,阻止它运行调度的回调.通常情况下,上下文将是UI线程,通常这很明显,因为它会锁定您的应用程序UI.

如果您可以使用VS调试器附加并观察发生的情况,请尝试暂停并查看Parallel Stacks视图.这应该有助于缩小考虑的可能性.

正如斯蒂芬指出的那样,当你称之为“即发即忘”时,也可能发生异常.如果您还没有,请确保您处理TaskScheduler.UnobservedTaskException以记录此类事件.请注意,这是从终结器调用的,因此调用它的时间是不确定的.这可能会使调试变得棘手,因为事件可能要比导致异常的实际事件晚得多.因此,我建议遵循Stephen的建议并将任务保存到等待或稍后等待其他地方.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读