我有以下客户端-服务器样式的伪代码:
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();
在这种脱机的情况下,这可能吗?我该怎么做呢?
答案 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
。但我希望您能掌握基本的想法。