在断开连接的情况下将同步代码包装到异步等待中

Wrap synchronous code into async await in disconnected scenario

我有以下客户端-服务器风格的伪代码:

public void GetGrades() {
   var msg = new Message(...); // request in here
   QueueRequest?.Invoke(this, msg); // add to outgoing queue
}

在另一个处理器中 class 我有一个循环 :

// check for messages back from server
// server response could be a "wait", if so, wait for real response
// raise MessageReceived event here
// each message is then processed by classes which catch the event

// send new messages to server
if (queue.Any()){
  var msg = queue.Dequeue();
  // send to server over HTTP 
}

我已经大大简化了这段代码,因此很容易看出我的问题的目的。

目前我这样称呼这段代码:

student.GetGrades(); // fire and forget, almost

但是我知道结果何时返回的方式不太理想,我基本上使用事件:

我提高 MessageReceived?.Invoke(this, msg); 然后在另一个级别捕获它 StudentManager 将结果设置在特定的学生对象上。

但是我想把它包装在 async await 中,并有类似这样的东西:

var grades = await GetGrades();

在这种断开连接的情况下这可能吗?我该怎么做?

您可以尝试使用 TaskCompletionSource。你可以这样做

TaskCompletionSource<bool> _tcs; 
public Task GetGrades() {
   var msg = new Message(...); // request in here
   QueueRequest?.Invoke(this, msg); // add to outgoing queue
   _tcs = new TaskCompletionSource<bool>();
   return _tcs;
}

然后当您需要确认任务是否已完成时,您就可以了。

_tcs.TrySetResult(true);

通过这样做你可以做到:

var grades = await GetGrades();

当然这里还有另外的事情要解决。如果可以多次调用,您将把那些 TaskCompletionSource 保存在哪里,以及如何 link 每条消息发送给每个 TaskCompletionSource。但我希望你能理解基本的想法。