Windows 10 LTSB和C#Winforms-线程问题
所以我这里的问题很简单。我设计了一个WinForms应用程序,它在我的机器(Win7)和其他机器上运行得很好,但当我在Windows 10 2016 LTSB机器上运行该应用程序时,我的后台线程并不像预期的那样工作,但有些线程的性能确实如预期的那样 申请流程:Windows 10 LTSB和C#Winforms-线程问题,c#,multithreading,windows-10,C#,Multithreading,Windows 10,所以我这里的问题很简单。我设计了一个WinForms应用程序,它在我的机器(Win7)和其他机器上运行得很好,但当我在Windows 10 2016 LTSB机器上运行该应用程序时,我的后台线程并不像预期的那样工作,但有些线程的性能确实如预期的那样 申请流程: 等待1分钟(带线程计时器的obj1) Post事件(当主窗口调用obj1时来自obj1的字符串消息) 更新表单文本(带有来自事件消息的信息) 执行操作(后台线程) 发布事件消息(从后台线程到主窗口) 等待随机周期(带线程计时器的obj1
- 等待1分钟(带线程计时器的obj1)
- Post事件(当主窗口调用obj1时来自obj1的字符串消息)
- 更新表单文本(带有来自事件消息的信息)
- 执行操作(后台线程)
- 发布事件消息(从后台线程到主窗口)
- 等待随机周期(带线程计时器的obj1)
- Post事件(来自obj1的字符串消息)
- 更新表格
- 等一分钟
class MainWindow
{
List<Controller> controllers = new List<Controller>();
List<ControllerDisplay> controllerDisplays = new List<ControllerDisplay>();
Queue<string> requests = new Queue<string>();
private void AppLifetimeLoopCallback(object state)
{
while (requests.Count > 0)
{
string request = requests.Dequeue();
string response = controllers[i].ProcessRequest(request);
string anotherResponse = controllerDisplays[i].ProcessResponse(response);
if (!string.NullOrWhiteSpace(anotherResponse))
{
requests.Enqueue(anotherResponse);
}
}
for (int i = 0; i < controllers.Count; i++)
{
requests.Enqueue("STATE?");
}
timer.Change(300, Threading.Timeout.Infinite);
}
}
class Controller
{
public string ProcessRequest(string request)
{
switch (request)
{
case "STATE?":
if (shouldRequest)
{
return "REQ:1234";
}
else if (isProcessing)
{
return "PRQ:1234";
}
else
{
return "IDLE";
}
break;
case "APPROVE":
shouldRequest = false;
isProcessing = true;
thread = new Threading.Thread(new ThreadStart(() =>
{
Threading.Thread.Sleep(300);
isProcessing = false;
return "RQF:1234";
})
{
IsBackground = true,
};
thread.Start();
break;
case "DENY:
shouldRequest = false;
break;
}
}
}
class ControllerDisplay
{
public string ProcessResponse(string response)
{
switch (request.Substring(0, 4))
{
case "REQ:":
thread = new Threading.Thread(new ThreadStart(() =>
{
// perform some checks
if (isValid)
{
return "APPROVE";
}
else
{
return "DENY";
}
})
{
IsBackground = true,
};
thread.Start();
break;
case "RQF:":
thread = new Threading.Thread(new ThreadStart(() =>
{
// finalize and cleanup request bits
return "APPROVE";
})
{
IsBackground = true,
};
thread.Start();
break;
case "PRQ:":
// update UI
break;
}
}
}
我要结束这个问题,因为这完全是废话,我为他们花在阅读这篇文章上的时间向他们道歉 因此,
队列
上的手动锁以前一直导致死锁,因此它们被移除。现在,它一开始似乎解决了这个问题,但长时间运行的测试证明,时不时(我认为是Windows问题)会出现死锁
我之所以认为这是Windows的问题,是因为有人告诉我,这是他们在Windows上的体验,这肯定是Windows的问题。没有看不起任何人,但他不做线程,因为他不知道如何做,提到的结果是他试图做线程。从这里吸取的教训
谢谢各位
编辑:
问题已经解决,长期运行的测试到目前为止看起来非常有希望。为了实现这一点,我只需将
Queue
更改为ConcurrentQueue
,并在需要的地方对代码进行一些修改(即ConcurrentQueue.Clear()
不存在于Queue.Clear()
存在的地方)。让你的应用程序生成日志文件,然后在所有必要的地方添加日志条目。通过阅读和比较日志文件,您应该能够了解可能的错误。一种更快的方法是实时调试,但不确定是否允许直接在Windows 10机器上工作。请考虑方法。然后可以将代码简化两次。还要将.NET版本目标至少更新到4.6。有关TPL的更多信息:手动实现的状态机可以替换为简单的线性async
方法。Asasync/await
实现状态机本身。异步编程现在在C#中尽可能简单。请注意太旧的代码。您好@aepot,我将快速查看TPL谢谢。至于“状态机”,有一个物理外部设备,我正在模拟它来为应用程序提供测试运行。原始代码实际上与一个串行端口通信,该设备是一个128Kb的ARM处理器。我不允许更改设备,只能更改调节设备的应用程序。谢谢您的时间。@aepot,我正在使用NET4.7.2。目前我认为我发现了问题。我将队列更改为ConcurrentQueue。我在队列上有手动锁,但我以前删除过这些锁,以删除排队/出列事件处理程序上发生的死锁。我想一些我没有记录的东西悄无声息地死掉了——尽管如此,仍然在测试。现在有一个不同的问题,我将不得不通过CreateProcessAsUser
从advapi32.dll
lock (checkLock)
{
if (isProcessingRequest)
{
break;
}
else
{
lock (resourceLock)
{
isProcessingRequest = true;
}
}
}
thread = new Threading.Thread(new ThreadStart(() =>
{
lock (resourceLock)
{
// finalize and cleanup request bits
isProcessingRequest = false;
}
return "APPROVE";
})
{
IsBackground = true,
};
thread.Start();