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
クラスを使用して、サーバー側に 2 つのメソッドが必要です。
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);
この問題は解決しません。
この問題を解決する方法はありますか?
前もって感謝します!