在应用程序启动时启动计时器间歇性死锁
我有一个具有两个独立GUI线程的应用程序,并且主窗体在每个线程上运行。 (这是为了允许同时在不同屏幕上的独立用户)在应用程序启动时启动计时器间歇性死锁
这些窗口中的每一个窗口都有一个InactivityTimer组件,它用于在用户在一段时间内不活动后重新回到主页。
主要功能的相关部分:
static void Main()
{
MainWindow form1 = new MainWindow(true);
//check that we have a second screen
if (Screen.AllScreens.Length > 1)
{ //Setup the second screen on its own thread and bind events between the two
System.Threading.Thread thread = new System.Threading.Thread(() =>
{
MainWindow form2 = new MainWindow(false);
form2.FormClosed += (o, e) =>
{
form1.Invoke((MethodInvoker)delegate
{
form1.Close();//close form1 when form2 closes. we dont need vice-versa because form2 is on a background thread.
});
};
/* Logic that binds events between the two forms*/
Application.Run(form2);
})
{ IsBackground = true };
thread.Start();
}
Application.Run(form1);
}
的静止定时器:
public partial class InactivityTimer : System.Windows.Forms.Timer, IMessageFilter
{
public InactivityTimer()
{
Initialise();
}
public InactivityTimer(IContainer container)
{
Initialise();
container.Add(this);
}
private void Initialise()
{
InitializeComponent();
Application.AddMessageFilter(this);
}
public void ResetTimer()
{
Stop();
Start();
}
public bool PreFilterMessage(ref Message m)
{
bool watching = /*logic that determines whether this is a message we are watching for (mainly mouse actions)*/;
if (watching)
{
ResetTimer();
}
return false;//do not stop the event being dispatched
}
}
当我启动应用程序,其中一个画面总是先于另一个显示出来,这并不令人意外。但有时(并非总是),当我在该屏幕与其他屏幕出现之前进行交互时,应用程序停止,就像死锁一样。第二个屏幕从不显示,第一个屏幕停止响应输入。
如果我在调试模式下发生这种情况时'断线全部',则应用程序始终停留在InactivityTimer的ResetTimer()
中的Start();
上。
我曾经见过类似的行为之前,我认为这是因为它有时会在它的父控件的句柄被创建之前启动,而且如果IsHandleCreated为false,则不会尝试启动计时器。
但是:
a)我甚至不知道这不仅仅是固定它的时间的改变;
b)在这种情况下,我非常确定,自窗口显示以来,父句柄已经创建;
c)同样的修复方法没有在这里工作。
我一直在挖掘这一段时间,并获得无处不在。更糟的是,我似乎无法在削减的应用程序中复制这个问题。但我无法想象任何会阻碍计时器在停止工作后自动启动的计时器。
如果有人可以请弄清楚发生了什么事情和/或找出它的修复程序这将是惊人的。
我只是今天才知道发生了什么,因为调试器突然停在了一个完全不同的地方。
rory.ap在评论中是正确的,只有像锁等事情会导致这样的僵局。然而,当我查看我的代码时,它从来没有点击过Invoke
就像这样的构造(关于UI线程),所以我没有注意到这些。
但是,今天我的注意力被吸引到它,低看,我有一个lock
内Invoke
,这是造成死锁。
您的应用程序中是否存在您未在此显示的任何同步机制,例如锁或信号灯? –
我在不同的地方使用了'lock(/ * lock object * /){}'块,但是这些都是小部分,它们做的并不多,在应用程序的完全不相关的部分使用了不同的锁对象。在最糟糕的情况下,我可能会遇到少量争用,但没有死锁。 – fweaks
这些是唯一会导致死锁的事情。如果我们有机会帮助你解决问题,你需要向我们展示所有相关的代码。 –