C#线程使用Task来替代Thread,但是在项目中却遇到用户反馈某些功能不执行。
可能的原因有:
一、系统CPU、内存使用率已经接近饱和
将代码由原本的:
Task.Factory.StartNew(() =>{});
修改为:
Task.Factory.StartNew(() =>{}, TaskCreationOptions.LongRunning); 使用独立线程,不被线程池控制,否则可能资源不足线程池不排档期。
二、电脑自动休眠
电脑休眠后,线程不再执行。
解决方法:让用户禁止电脑休眠,或者在软件启动时用代码控制电脑不休眠。
[DllImport("kernel32.dll")]
public static extern uint SetThreadExecutionState(uint esFlags);
public const uint ES_AWAYMODE_REQUIRED = 0x00000040;
public const uint ES_CONTINUOUS = 0x80000000;
public const uint ES_DISPLAY_REQUIRED = 0x00000002;
public const uint ES_SYSTEM_REQUIRED = 0x00000001;
/// <summary>
/// 阻止系统睡眠
/// </summary>
public static void StopSystemSleep()
{
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
}
/// <summary>
/// 恢复系统睡眠设置
/// </summary>
public static void RestoreSystemSleep()
{
SetThreadExecutionState(ES_CONTINUOUS);
}
三、Task中代码异常
Task中的代码异常会导致线程退出,自然就不会继续执行其中的代码。
建议将Task内执行代码用try-catch捕获异常,这样能及时发现问题。
如果已经添加了try-catch,还是不执行,那么可能是因为Task中调用了外部组件的方法,外部组件抛出异常是无法被try-catch捕获到的,也就导致Task也退出。
解决方法是在Task中嵌套一个子Task等待其执行完成,这样就算子Task异常退出了,主Task还存活。
代码如下:
Task.Factory.StartNew(() =>
{
var subTask = Task.Run(()=>
{
//这里写可能退出线程的代码
});
subTask.Wait();
},
TaskCreationOptions.LongRunning);
四、更多原因,持续更新中……(欢迎评论区提供原因,一起完善本文档)