【问题标题】:Wrap synchronous code into async await in disconnected scenario在断开连接的情况下将同步代码包装到异步等待中
【发布时间】:2019-03-28 14:35:14
【问题描述】:

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

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

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

【问题讨论】:

  • 你怎么知道 RequestSomething 已经完成了?
  • @hardkoded 我已经更新了我的问题
  • 如果你想阻塞直到 Queued 项目被处理,似乎队列是没有必要的。在您的情况下,队列的目的是什么?
  • @AlenGenzić 最终用户可能会排队许多不同的请求,我希望它们按顺序发送到服务器。同样因为服务器呼叫我,我在响应中发送消息,我必须等待,队列允许我在呼叫到来时保持我想要发送的准备就绪。

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


【解决方案1】:

您可以尝试使用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。但我希望你能得到基本的想法。

【讨论】:

  • 谢谢!我想这就是我缺少的魔法酱。我会试一试并标记为已回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-22
  • 1970-01-01
  • 2014-02-19
  • 1970-01-01
  • 2016-12-14
相关资源
最近更新 更多