【问题标题】:ContinueWith waits until main long polling Thread wakes upContinueWith 等到主长轮询线程唤醒
【发布时间】:2014-01-15 13:32:32
【问题描述】:

主应用线程使用发送/接收 TCP Socket 轮询服务器:

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 事件上的服务器通信有时会等到主线程从 Sleep(1000) 唤醒。

我期望的是独立执行,在 TCP 套接字上有一个独特的锁定部分和一个监视器,以避免多次点击(两者都确实有效)。

我知道 Task 对象具有“我将尽快执行此操作”的语义,但我无法弄清楚为什么它会在这种情况下等待。

【问题讨论】:

    标签: c# wpf multithreading sockets .net-4.0


    【解决方案1】:

    SyncRoot 是否来自某个 UI 控件?如果是这样,我猜您在与 UI 元素同步时遇到了隐式 UI 块。相反,为什么不创建一个完全独立于另一个对象的单独对象来锁定它。

    旁注,您可能希望让您的线程成为后台线程,以防您的应用程序关闭。

    【讨论】:

    • SyncRoot 是我的 Button ViewModel 中为锁定目的而创建的对象。我用它来避免在同一个按钮上多次点击发送,实际上 UI 是反应式的。 +1 后台线程提示!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-04
    • 2017-02-13
    • 2014-07-15
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多