从 onreceived 方法调用服务器方法的 SignalR 问题
SignalR issue with invoking server method from onreceived method
我有以下用于桌面客户端的 SignalR 代码:
_hub.On<String>("Ping",(string s) =>
{
Console.WriteLine(s + " from MainHub ");
_hub.Invoke("Acknowledge","Say Hello to MainHub");
});
I have Ping and Acknowledge method on Hub.
But
_hub.Invoke("Acknowledge","Say Hello to MainHub");
未从桌面客户端正确启动。
如何正确编写这段代码?
根据这个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
});
我有以下用于桌面客户端的 SignalR 代码:
_hub.On<String>("Ping",(string s) => { Console.WriteLine(s + " from MainHub "); _hub.Invoke("Acknowledge","Say Hello to MainHub"); });
I have Ping and Acknowledge method on Hub. But
_hub.Invoke("Acknowledge","Say Hello to MainHub");
未从桌面客户端正确启动。 如何正确编写这段代码?
根据这个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
});