【问题标题】:Handle UI events with socket interaction purpose in multithreaded environment在多线程环境中处理具有套接字交互目的的 UI 事件
【发布时间】:2013-12-18 10:36:41
【问题描述】:

在我的 MVVM 视图中,一些按钮显示对服务器获取状态响应的闪烁反应。

单个按钮在鼠标按下时发送一个同步套接字请求,在鼠标按下时发送一个同步套接字请求,并在发送的每条消息上增加 ID。在收到我的客户时,检查响应 ID 是否是预期的,丢弃意外的。在几毫秒内多次按下按钮会使传出消息 ID 增量过快,并且服务器响应未对齐。

为了解决这种错位问题,我们设置了一个锁,不仅在插座上,还在按钮上(呜呜!)以防止多次点击。

在我看来,这似乎是一种糟糕的设计实践,我想知道是否有更好的方法来实现响应性和消息对齐。

注意:没有编写代码,因为在我看来,它更像是一种设计实践而不是代码模板。

编辑:我的一个想法是如果第一个事件尚未提供,则丢弃多个鼠标按下事件,但似乎 WPF 自己将事件排入队列以 FIFO 方式引发它们。我正在使用 EventToCommand,但看不到要设置的 Handled 属性。

【问题讨论】:

    标签: c# wpf multithreading sockets


    【解决方案1】:

    我已经解决了一个非常简单但有效的方法。

    EventToCommandPreviewMouseDownPreviewMouseUp 事件路由到Execute_DownCommandExecute_UpCommand

    Execute_DownCommand:

    public void Execute_DownCommand()
        {
           DownWorkTask = Task.Factory.StartNew(() =>
                    {
                        if (!Monitor.TryEnter(SyncRoot))
                        {
                            return;
                        } // Don't let  multiple threads in here at the same time.
    
                        try
                        {
                          // Do Something
                        }
                        finally
                        {
                            Monitor.Exit(SyncRoot);
                        }
                    });
        }
    

    和 Execute_UpCommand:

    public void Execute_UpCommand()
        {
           DownWorkTask.Wait(); // The release waits for the pressed work completion and starts without locking the UI
    
           Task.Factory.StartNew(() =>
            {
                if (!Monitor.TryEnter(SyncRoot))
                {
                    return;
                } // Don't let  multiple threads in here at the same time.
    
                try
                {
                    // Do Up Work
                }
                finally
                {
                    Monitor.Exit(SyncRoot);
                }
            });
        }
    

    Monitor 的作用类似于锁,但允许在没有队列的情况下跳过多次强制点击。 我使用了Task Wait,因为我需要完成发送服务器请求的两半的“点击”事件。在网络包装类上,我可以锁定套接字,允许按下多个按钮。

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多