SignalR 无法拥有返回值的客户端方法。所以我正在尝试创建一个帮助类来实现这一点。
所以这就是我想要做的:
- 服务器端:调用客户端方法并提供唯一的请求id
Client(clientId).GetValue(requestId)
- 服务器端:保存 requestId 并等待回答使用
ManualResetEvent
- 客户端:内部
void GetValue(Guid requestId)
调用服务器方法hubProxy.Invoke("GetValueFinished", requestId, 10)
- 服务器端:通过requestId找到等待方法=>设置返回值=>设置信号
- 服务器端:方法不再等待 vor
ManualResetEvent
并返回检索到的值。
不幸的是,我能够让它工作。这是我的代码:
public static class MethodHandler
{
private static ConcurrentDictionary<Guid, ReturnWaiter> runningMethodWaiters = new ConcurrentDictionary<Guid,ReturnWaiter>();
public static TResult GetValue<TResult>(Action<Guid> requestValue)
{
Guid key = Guid.NewGuid();
ReturnWaiter returnWaiter = new ReturnWaiter(key);
runningMethodWaiters.TryAdd(key, returnWaiter);
requestValue.Invoke(key);
returnWaiter.Signal.WaitOne();
return (TResult)returnWaiter.Value;
}
public static void GetValueResult(Guid key, object value)
{
ReturnWaiter waiter;
if (runningMethodWaiters.TryRemove(key, out waiter))
{
waiter.Value = value;
}
}
}
internal class ReturnWaiter
{
private ManualResetEvent _signal = new ManualResetEvent(false);
public ManualResetEvent Signal { get { return _signal; } }
public Guid Key {get; private set;}
public ReturnWaiter(Guid key)
{
Key = key;
}
private object _value;
public object Value
{
get { return _value; }
set
{
_value = value;
Signal.Set();
}
}
}
使用这个MethodHandler
类我需要有两个方法服务器端:
public int GetValue(string clientId)
{
return MethodHandler.GetValue<int>(key => Clients(clientId).Client.GetValue(key));
}
public void GetValueResult(Guid key, object value)
{
MethodHandler.GetValueResult(key, value);
}
客户端实现是这样的:
// Method registration
_hubProxy.On("GetValue", new Action<Guid>(GetValue));
public void GetValue(Guid requestId)
{
int result = 10;
_hubConnection.Invoke("GetValueResult", requestId, result);
}
问题:
如果我打电话给服务器端GetValue("clientid")
。不会调用客户端方法。如果我注释掉returnWaiter.Signal.WaitOne();
,则调用客户端GetValue
并调用服务器端GetValueResult
。但是当然这次方法已经返回了。
我认为这与,ManualResetEvent
但即使使用while(!returnWaiter.HasValue) Thread.Sleep(100);
也无法解决此问题。
任何想法如何解决这个问题?
提前致谢!