【问题标题】:SignalR WPF StateChange IssuesSignalR WPF 状态更改问题
【发布时间】:2014-08-05 23:12:23
【问题描述】:

我正在编写一个小 WPF 应用程序来测试一些 SignalR 代码。一切都从我写的东西开始,但我偶然发现了一些我不确定的东西。

我为HubConnection StateChanged 事件创建了一个事件处理程序;

_hub.StateChanged += (change) =>
{ 
    Console.WriteLine("hubConnection.StateChanged {0} => {1}", change.OldState, change.NewState);

    if (change.NewState == ConnectionState.Connecting)
    {
        statusCallBack callBack = new statusCallBack(UpdateStatus);
        this.Dispatcher.Invoke(callBack, "hubConnection.StateChanged");
    }
    if (change.NewState == ConnectionState.Connected)
    {
        Console.WriteLine("hello");
        statusCallBack callBack = new statusCallBack(UpdateStatus);
        this.Dispatcher.Invoke(callBack, "hubConnection.StateChanged");
    }
};

使用我的 Delegate 方法 statusCallBack 和方法;

delegate void statusCallBack(string msg);

private void UpdateStatus(string msg)
{
    if (this.Dispatcher.CheckAccess() == true)
    {                
        this.tbStatus.AppendText(Environment.NewLine + DateTime.Now.ToLongTimeString() + " --- " + msg);
        this.tbStatus.CaretIndex = this.tbStatus.Text.Length;
        this.tbStatus.ScrollToEnd();
    }
}

现在我可能在这里遗漏了一些非常明显的东西,但是当在StateChanged 处理程序中检查ConnectionState.Connecting 并将消息输出到我的标签时它工作正常。

然后,当 SignalR HubConnection 状态更改为 ConnectionState.Connected 并且我尝试调用委托时,WPF 应用程序就会锁定。

它将正常输出到控制台,并检查是否change.NewState == ConnectionState.Connected,然后将“hello”输出到控制台,但随后就冻结了。

如果我调试应用程序,当它进入 Connected if 语句时,对象 change.NewStatechange.OldState 会出现以下错误消息。

View larger image here.

我不知道为什么它在第一个 if 语句中起作用,但在第二个语句中不起作用。还有为什么它能够将正确的值输出到控制台?

即使我注释掉最初的if 语句以检查Connecting,它仍然会在Connected 时冻结。

【问题讨论】:

    标签: c# signalr dispatcher signalr.client


    【解决方案1】:

    这是从事件回调 UI 时常见的死锁问题。

    尝试使用Dispatcher.BeginInvoke 而不是Invoke

    this线程中所引用:

    当您使用 Dispatcher.BeginInvoke 时,这意味着它会调度 给定稍后在 UI 线程中执行的操作, 然后返回控制以允许当前线程继续 执行。 Invoke 会阻止调用者,直到计划的操作 完成。

    附带说明:MVVM Light 有一个非常有用的助手,称为 DispatcherHelper,它不仅与几乎所有东西(WPF、WinRT、SL 等)兼容,而且使用起来非常简单。它可以帮助您自动将调用分派回 UI。如果不出意外,将 NUGet 包仅用于此功能可能会有所帮助。

    【讨论】:

    • 非常感谢。我现在可以继续我的生活了:P 我会检查 MVVM Light。
    • 是的!尽管System.Threading.Thread.CurrentThread == System.Windows.Threading.Dispatcher.CurrentDispatcher.Thread 是真的,当您收到错误This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.' 时肯定有问题
    猜你喜欢
    • 1970-01-01
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多