首页 新闻 会员 周边 捐助

异步和多线程,长时间运行,会被优化/跳过怎么办?

0
悬赏园豆:30 [待解决问题]

这是一个C# Windows Form程序。作为游戏Service的一个后端服务,通过接收RabbitMQ消息,来处理充值、游戏记录,然后产生一些成就和奖励。

外层是通过多线程的方式,来启动一个Task执行。

内部是使用了多个异步(async)等待(await)来完成具体的业务。

问题出现在长时间高负荷运行的情况下,异步内部的代码就会离奇的消失了,根本没有执行。
看log(log4net)的话,能看到,程序执行是可以进入Task的,但是后面的代码就没有了。

一开始,我以为是其中一部分代码异常过多,被GC优化了。我就把出现异常的地方添加了一些代码做了相应的处理。后来不报异常了,代码仍然会被优化或者说被跳过。
以前我遇到过类似的问题,跟我同事请教,同事告诉我跟微软的线程池管理有关,让我不要用微软的线程池。

再说一遍,多线程也好、异步也好,都是是没有问题的(至少表面上是没有),长时间、高负载的情况下才会出现问题。而且出现问题以后,是所有的这部分代码都不执行了,而不是其中有的执行有的不执行。

当前任务Task执行的方式是TaskCreationOptions.HideScheduler

是不是需要更换其它方式:

https://learn.microsoft.com/zh-cn/dotnet/api/system.threading.tasks.taskcreationoptions?view=netframework-4.5.2&devlangs=csharp&f1url=%3FappId%3DDev16IDEF1%26l%3DZH-CN%26k%3Dk(System.Threading.Tasks.TaskCreationOptions.HideScheduler)%3Bk(SolutionItemsProject)%3Bk(TargetFrameworkMoniker-.NETFramework%2CVersion%253Dv4.5.2)%3Bk(DevLang-csharp)%26rd%3Dtrue

柳城之城的主页 柳城之城 | 初学一级 | 园豆:39
提问于:2023-11-09 11:30

里面有没有出现死循环,导致一直占用线程不撒手的,然后后面的线程只能排队进不去

百鸟朝凤 1年前
< >
分享
所有回答(5)
0

代码没问题考虑下计算机的问题,计算机会优先执行高权重的任务,其次在cpu资源不足时可能会释放掉长时间未访问、长时间未变化的任务

TenFly | 园豆:69 (初学一级) | 2023-11-10 11:59
0

1.async\await 使用越少键越好,await本质是状态机,编译器本质上是会生成一个自动类,用于记录await状态,存储每个await里面的方法作为 delegate,所以理论上越少越好;
参考:https://learn.microsoft.com/zh-cn/archive/msdn-magazine/2011/october/asynchronous-programming-async-performance-understanding-the-costs-of-async-and-await
2.死锁,可以参照这个帖子看一下
https://www.cnblogs.com/heyuquan/p/async-deadlock.html
3.线程过多,有可能假死的任务建议增加超时机制,参考帖子看一下
https://www.cnblogs.com/xiaohemiao/p/17503559.html

小树禾小央 | 园豆:204 (菜鸟二级) | 2023-11-10 16:26
0

为何不另起一个线程,里面写个死循环?

秋叶愁 | 园豆:202 (菜鸟二级) | 2023-11-11 11:11
0

老老实实的用 Queue + Thread 处理吧!越老土越稳定。

问题可能出在Task嵌套上,看看这个
https://www.cnblogs.com/micro-chen/p/17006135.html

异常尽量在 Task 内部处理,IsFaulted 这种判断不那么靠谱。

Task.Factory.StartNew() 返回的也是一个任务,最好 Wait() 或 await

Adming | 园豆:119 (初学一级) | 2023-11-16 21:31
0

将task设置成LongRunning,线程池就不会被该任务阻塞

超级小屁屁 | 园豆:204 (菜鸟二级) | 2024-09-30 16:56
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册