主应用程序线程使用发送/接收TCP套接字轮询服务器:
public void Run(){
var updateThreading = new System.Threading.Thread(() =>
{
while (KeepRunning)
{
System.Threading.Thread.Sleep(1000);
try
{
// Send and receive via TCP socket
var response = SendAndReceive();
Callback(response);
}
catch (Exception exception)
{
}
}
});
updateThreading.Start();
}
WPF按钮提供以分离方法管理的鼠标按下/鼠标按下操作。在鼠标按下事件时,任务在主线程使用的同一套接字上发出服务器请求,而在鼠标启动时,我继续执行相同的任务,以确保始终执行“压力已完成”的服务器请求。
这是鼠标按下的代码:
public override void Execute_CommandDown()
{
DownWorkTask = Task.Factory.StartNew(() =>
{
if (!Monitor.TryEnter(SyncRoot))
{
return;
} // Don't let multiple threads in here at the same time.
try
{
DoDownWork(); // send / receive via the same TCP socket of the main thread
}
finally
{
Monitor.Exit(SyncRoot);
}
});
}
这是鼠标的代码。
public override void Execute_CommandUp()
{
// Make a continuation here...
DownWorkTask.ContinueWith(t =>
{
if (!Monitor.TryEnter(SyncRoot))
{
// Don't let multiple threads in here at the same time.
return;
}
try
{
DoUpWork();// send / receive via the same TCP socket of the main thread
}
finally
{
Monitor.Exit(SyncRoot);
}
});
}
UI线程永远不会冻结(在我的Callback
代码中Dispatcher
有效地更新GUI),按下/释放按钮是被动的,操作按顺序“正确”执行。
我注意到,鼠标X事件上的服务器通信有时会等待,直到主线程从休眠状态唤醒(1000)。
我期待的是一个独立的执行,在TCP套接字和监视器上有一个独特的锁定部分,以避免多次点击(两者都确实有效)。
我知道Task对象有一个“我会尽快这样做”的语义,但我无法弄清楚为什么它会在这种情况下等待。
答案 0 :(得分:1)
SyncRoot
是否有某些UI控件出现了什么?如果是这样,我猜你在与UI元素同步时遇到了一个隐含的UI块。相反,为什么不创建一个单独的对象来锁定它完全独立于另一个对象。
旁注,您可能希望在应用程序关闭时使您的线程成为后台线程。