在断开连接的场景中将同步代码包装到异步等待中

问题描述 投票:0回答:1

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

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

在这种断开连接的场景中这可能吗?我该怎么做呢?

c# http async-await client-server
1个回答
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。但我希望你能得到基本的想法。

© www.soinside.com 2019 - 2024. All rights reserved.