- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在.NET 4.5上有一个C#Windows窗体应用程序。
该应用程序连接到USB设备。
我想同时支持多个 session 。
为此,我需要在 session 锁定时从该设备断开连接,以允许新 session 连接到该设备。
我使用SystemEvents.SessionSwitchEventArgs.Reason来检测此类事件:
- session 切换上的SessionSwitchReason.ConsoleDisconnect
-SessionSwitchReason.ConsoleConnect在 session 切换后解锁
此事件似乎是完美的解决方案,但有时在随机时间(经过多次锁定或解锁后),该事件不会触发并且UI冻结。
值得注意的是,当应用程序在调试器中运行时,不会发生这种情况。
我从日志中知道其他一些后台线程仍在正常工作,但UI冻结,并且未调用该事件的预订函数。
我的代码示例:
Program.cs:
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyProgram
{
static class Program
{
private static Mutex mutex = null;
[STAThread]
static void Main()
{
const string appName = "MyProgram";
bool createdNew;
mutex = new Mutex(true, appName, out createdNew);
if (!createdNew)
{
//app is already running! Exiting the application
return;
}
Application.EnableVisualStyles();
//This was one attempt to solve the UI deadlock Microsoft.Win32.SystemEvents.UserPreferenceChanged += delegate { };
Application.SetCompatibleTextRenderingDefault(false);
MyProgramEngine MyProgramEngine = new MyProgram.MyProgramEngine();
Application.Run(MyProgramEngine.getForm());
}
}
using log4net;
using log4net.Config;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using WindowsInput;
using System.Windows.Forms;
using Microsoft.Win32;
namespace MyProgram
{
class MyProgramEngine
{
private MainForm mainForm;
public MyProgramEngine()
{
XmlConfigurator.Configure();
Utility.logger.Info(string.Format("MyProgram Started. Version: {0}", Application.ProductVersion));
SystemEvents.SessionSwitch += new SessionSwitchEventHandler(SystemEvents_SessionSwitch);
if (!GlobalSettings.getInstance().isProperlyConfigured())
{
WarningForm warningForm = new WarningForm("MyProgram is not properly configured. Please contact support");
warningForm.ShowDialog();
Application.Exit();
Environment.Exit(0);
}
mainForm = new MainForm();
initArandomBackgroundThread();
initDeviceThread();
}
private void initDeviceThread()
{
Thread detectAndStartReader = new Thread(initDevice);
detectAndStartReader.IsBackground = true;
detectAndStartReader.Start();
}
public void initDevice()
{
//Connect to device
//Start device thread
}
public MainForm getForm()
{
return mainForm;
}
//Handles session switching events
internal void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
{
try
{
if (e.Reason.Equals(SessionSwitchReason.ConsoleDisconnect))
{
DisconnectFromDevice();
TerminateDeviceThread();
}
else if (e.Reason.Equals(SessionSwitchReason.ConsoleConnect))
{
initDeviceThread();
}
else
{
Utility.logger.Info("The following SesseionSwitchReason has been caught: " + e.Reason + " , No action!");
}
}
catch (Exception ex)
{
Utility.logger.Error("Something bad happened while managing session switching events", ex);
}
}
}
最佳答案
我发现了错误所在。
简单来说,
永远不要在后台工作线程上创建控件。
在我的代码中,如果删除了SessionSwitch事件订阅,则仍然会发生挂起。我能够将主线程上的等待追溯到SystemSettingsChanging,它也是一个SystemEvent,但我不控制。
在我几乎放弃尝试解决此问题后,我逐行阅读了代码,这使我发现正在后台线程上创建一个Form(弹出窗口)。
如上面给出的示例所示,这部分代码没有引起我的注意。
initArandomBackgroundThread();
This occurs if a control is created on a thread which doesn't pump messages and the UI thread receives a WM_SETTINGCHANGE message.
Common causes are a splash screens created on a secondary UI thread or any controls created on worker threads.
Applications should never leave Control objects on threads without an active message pump. If Controls cannot be created on the main UI thread, they should be created on a dedicated secondary UI thread and Disposed as soon as they are no longer needed.
One way to identify which windows are created on which thread is with Spy++ in the Processes view (Spy.Processes menu). Select the hung process and expand its threads to see if there are any unexpected windows. This will find the native window if it still exists; however, the problem can occur even if the native window has been destroyed, so long as the managed Control has not yet been Disposed.
关于c# - SystemEvents.SessionSwitch导致我的Windows窗体应用程序卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45707940/
对于一个科学实验,我写了一个turtle.py ,它会打开一个 800x480 的窗口并绘制一个缓慢增长的黑点。 turtle.py以 C:\Users\kaza>python C:\Users\ka
我开发了一个 swing 应用程序,但每次运行应用程序时都会打开一个新窗口。我希望如果一个窗口已经打开,则其他窗口不允许打开。 最佳答案 Here是一个 Java 单一应用实例的例子: A singl
有没有办法检测主进程中 Electron 的结构? process.platform 似乎也在 x64 机器上返回 win32,我没有在文档中找到任何获取架构的选项。 最佳答案 你试过 process
public short[] HanningWindow(short[] signal_in ,int pos ,int size) { for (int i= pos; i < pos+si
我有一个具有这些属性的 Electron 窗口: mainWindow = new BrowserWindow({ width: 800, height: 600, title: "Aqu
我有一个 Ubuntu 工作站,我正在尝试引导一个 Windows 节点。 Windows 节点在端口 2222 上打开了 ssh。我一直在关注 http://docs.opscode.com/plu
我是一名优秀的程序员,十分优秀!