我有一个在它自己的系统托盘中运行的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);
});
}
这看起来不错吗?它在我的本地机器上工作,但这有可能在我们的业务中的每台用户机器上推出,我需要做到正确。
答案 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");
}
});
}