我正在實現我的應用程序的網絡層,即使用異步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