我正在实现我的应用程序的网络层,即使用异步JSON-RPC协议。WinRT:阻止任务
为了与服务器通信,我想做一个方法,将发送一个正确的请求,等到服务器发送响应,并返回它。所有与使用异步/等待关键字。
这是简化的示例代码:
字符串响应;
Task<string> SendRequest(string methodName, string methodParams)
{
string request = generateRequest(methodName, methodParams);
await Send(request); // this will send using DataWriter, and StreamSocket
// block Task until response arrives
return response;
}
async void ReceiveLoop()
{
while (true)
{
uint numStrBytes = await _reader.LoadAsync(BufferSize);
string msg = _reader.ReadString(numStrBytes);
response = msg;
// unblock previously blocked SendRequest
}
}
}
async void main()
{
RecieveLoop();
}
async void SendButtonPressed()
{
string response = await SendRequest("Test method", "Test params");
Debug.WriteLine("Response = " + response);
}
这种模式的主要问题是这种阻塞行为。此操作应阻止当前任务,并允许处理超时。 我试过使用ManualResetEvent和WaitOne(int)来处理这个问题,但它冻结了整个Thread,并且因为我只使用async/await,所以它冻结了整个应用程序(UI Thread对我更精确)。
解决方案,对我来说看起来很hacky是我可以使用Task.Delay与CancellationTokens。
它看起来像这样:
...
CancellationTokenSource cts;
int timeout = 10000;
Task<string> SendRequest(string methodName, string methodParams)
{
... (prepare request, and send)
cts = new CancellationTokenSource();
try
{
await Task.Delay(timeout, cts.Token);
} catch(TaskCanceledException)
{
}
// do rest
}
async void ReceiveLoop()
{
// init recieve loop, and recieve message
cts.Cancel();
}
与解决方案(除了它看起来像一个黑客)是性能问题 - 每一个请求有抛出EXCETION,需要处理(在这种情况下跳过)。这一个是缓慢的,它伤害:)
我怎样才能以更优雅的方式做到这一点?是否有其他选项来阻止任务?
问题是我需要接收循环,因为这个应用程序将使用双向JSON-RPC,因此服务器可以随时在应用程序上执行远程方法。 应用程序应始终查找传入消息。 – Axadiw
我已经在此添加了我的想法。 – usr
好的,感谢这个,但正如我之前提到的,我需要处理超时。 有没有办法处理它比检查单独的线程更优雅,哪个TaskCompletionSource-s太旧,并手动完成它们? – Axadiw