0

バックグラウンドスレッドで実行されていると思われるサーバーからのsignalR接続で操作する必要がある、システムトレイで実行されている独自のUIスレッドで作成されたフォームがあります。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);
        });
    }

これは大丈夫に見えますか?これは私のローカル マシンで動作していますが、これは社内のすべてのユーザー マシンに展開される可能性があり、適切に処理する必要があります。

4

1 に答える 1

4

技術的には、リッスンOn<T>する前に( を使用して) すべての通知に接続する必要があります。Startあなたの非同期作業に関しては、あなたが何をしようとしているのかよくわかりませんが、何らかの理由で、UI への通知を、への呼び出しによって返された Task である変数に連鎖させて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");
        }
    });
}
于 2012-11-13T17:25:31.140 に答える