使用signalR更新Winforms UI

时间:2012-11-13 12:57:21

标签: asynchronous signalr signalr.client

我有一个在它自己的系统托盘中运行的UI线程上创建的表单,我需要使用来自服务器的signalR连接进行操作,我相信它在后台线程上运行。我知道在不从UI线程访问控件时需要调用控件。我可以使用在表单加载时调用的以下代码来操作(在我的情况下使弹出窗口)但是想要进行健全性检查,因为我对异步是相当新的:

 private void WireUpTransport()
    {
        // connect up to the signalR server
        var connection = new HubConnection("http://localhost:32957/");
        var messageHub = connection.CreateProxy("message");
        var uiThreadScheduler = TaskScheduler.FromCurrentSynchronizationContext();

        var backgroundTask = connection.Start().ContinueWith(task =>
        {
            if (task.IsFaulted)
            {
                Console.WriteLine("There was an error opening the connection: {0}", task.Exception.GetBaseException());
            }
            else
            {
                Console.WriteLine("The connection was opened successfully");
            }
        });

        // subscribe to the servers Broadcast method
        messageHub.On<Domain.Message>("Broadcast", message =>
        {
            // do our work on the UI thread
            var uiTask = backgroundTask.ContinueWith(t =>
            {
                popupNotifier.TitleText = message.Title + ", Priority: " + message.Priority.ToString();
                popupNotifier.ContentText = message.Body;
                popupNotifier.Popup();
            }, uiThreadScheduler);
        });
    }

这看起来不错吗?它在我的本地机器上工作,但这有可能在我们的业务中的每台用户机器上推出,我需要做到正确。

1 个答案:

答案 0 :(得分:2)

从技术上讲,您应该在On<T>收听之前连接所有通知(使用Start)。至于你的异步工作,我不太确定你要做什么,但出于某种原因,你将通知链接到On<T>中的用户界面到backgroundTask变量,这是任务通过致电Start给你回复。没有理由参与其中。

所以这可能是你想要的:

private void WireUpTransport()
{
    // connect up to the signalR server
    var connection = new HubConnection("http://localhost:32957/");
    var messageHub = connection.CreateProxy("message");
    var uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();

    // subscribe to the servers Broadcast method
    messageHub.On<Domain.Message>("Broadcast", message =>
    {
        // do our work on the UI thread
        Task.Factory.StartNew(
            () =>
            {
                popupNotifier.TitleText = message.Title + ", Priority: " + message.Priority.ToString();
                popupNotifier.ContentText = message.Body;
                popupNotifier.Popup();
            }, 
            CancellationToken.None,
            TaskCreationOptions.None,
            uiTaskScheduler);
    });

    connection.Start().ContinueWith(task =>
    {
        if (task.IsFaulted)
        {
            Console.WriteLine("There was an error opening the connection: {0}", task.Exception.GetBaseException());
        }
        else
        {
            Console.WriteLine("The connection was opened successfully");
        }
    });
}