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

时间:2019-03-28 14:35:14

标签: c# http async-await client-server

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

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

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

// 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();

在这种脱机的情况下,这可能吗?我该怎么做呢?

1 个答案:

答案 0 :(得分:2)

您可以尝试使用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保存在哪里,以及如何将每条消息链接到每个TaskCompletionSource。但我希望您能掌握基本的想法。