我有以下用于桌面客户端的SignalR代码:
_hub.On<String>("Ping",(string s) => { Console.WriteLine(s + " from MainHub "); _hub.Invoke("Acknowledge","Say Hello to MainHub"); });
我在Hub上有Ping和Acknowledge方法。 但是
_hub.Invoke("Acknowledge","Say Hello to MainHub");
未从桌面客户端正常启动。 如何正确编写此代码?
答案 0 :(得分:2)
根据Link
目前在.NET客户端中,我们在使用TaskQueue从服务器接收消息时序列化调用用户回调。这包括使用HubProxy.On注册的回调或HubProxy.Invoke之后的延续。 如果这些回调阻塞,特别是阻塞等待来自另一个回调的结果,则接收调度队列将停止(死锁)。 我们应检测此情况并在发生时跟踪错误(Connection.OnError)。 我们可以在TaskQueue本身(带有一个可选的标志,当然可以启用它)中执行此操作,这使得它实际上是监视自身,使用在第一个队列上启动的异步循环来检查当前运行的任务是否与正在运行的任务相同最后一个间隔。如果是,请记录错误。
现在我已经设法通过快速但又脏的解决方案解决了这个问题。我知道这不是解决这个问题的方法,但除此之外我别无选择。其他比这更好的解决方案非常受欢迎。
Threading.Timer tmr= new Threading.Timer(new TimerCallback(Acknowledge),null, 0, Timeout.Infinite);
private void Acknowldege(object state)
{
if(SignalRIsReady)//check if signalr is ready
{
_hub.Invoke("Acknowledge","Say Hello to MainHub");
tmr.Change(Timeout.Infinite, Timeout.Infinite);//wait until next event occurs
}
}
_hub.On<String>("Ping",(string s) =>
{
Console.WriteLine(s + " from MainHub ");
tmr.Change(50, Timeout.Infinite);// call callback after 50ms
});
我管理的另一个解决方案是使用configureawait。以下是解决方案:
_hub.On<String>("Ping",async(string s) =>
{
Console.WriteLine(s + " from MainHub ");
await Task.Run(async()=>{
_hub.Invoke("Acknowledge","Say Hello to MainHub");
}).ConfigureAwait(false);//this will run the task to seperate thread, unblocking the parent thread
});