我有以下客户端 - 服务器样式伪代码:
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();
在这种断开连接的场景中这可能吗?我该怎么做呢?
你可以尝试使用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
。但我希望你能得到基本的想法。