비동기 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)을 사용하여 처리하려고 시도했지만 전체 스레드가 고정되고 비동기/대기 만 사용하기 때문에 전체 응용 프로그램이 고정됩니다 (UI 스레드가 더 정확함).
나에게 꽤 해킹 된 해결책은 CancellationTokens와 함께 Task.Delay를 사용할 수 있다는 것입니다. 모든 처리 할 필요가 던져진 excetion이,이 요청 (이 경우에 생략 -
가...
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();
}
(가 해킹처럼 보인다 외에) 성능입니다 솔루션의 문제 :
그것은 다음과 같습니다). 이것은 느리고 아파요 :
어떻게하면 더 우아한 방법으로 할 수 있습니까? 작업을 차단할 다른 옵션이 있습니까? 나는 당신의 정확한 요구 사항을 모르기 때문에 당신도 다음 루프를 필요로하는 경우
while(!cancel) {
await sendRequest();
await receiveResponse();
}
확실하지 :
이 앱은 양방향 JSON-RPC를 사용하므로 서버에서 언제든지 원격 메소드를 실행할 수 있으므로 루프를 수신해야하는 문제가 있습니다. 앱에서 항상 수신 메일을 찾아야합니다. – Axadiw
나는 이것에 대한 나의 생각을 덧붙였다. – usr
좋아, 고마워,하지만 전에 언급했듯이, 나는 타임 아웃을 처리해야한다. TaskCompletionSource-s가 너무 오래된 별도의 스레드를 검사하는 것보다 더 우아하게 처리 할 수있는 방법이 있습니까? – Axadiw