循环等待两件事?
awaiting two things in a loop?
如何同时等待两个或更多的东西(不同类型)?就像在事件循环中一样:
while(true) {
Letter msg1 = await WaitForLetter();
//read msg1 and reply.
SMS msg2 = await WaitForSMS();
//read msg2 and reply
}
这看起来不对。两条消息最终会互相阻塞吗?
目前,您的代码将依次等待每个方法完成。如果你想发送每条消息然后在最后等待两者,你可以使用 Task.WaitAll
方法(假设你的方法 return 一个 Task<T>
对象。
while(true) {
Task<Letter> msgTask1 = WaitForLetter();
Task<SMS> msgTask2 = WaitForSMS();
Task.WaitAll(msgTask1, msgTask2);
}
然后您可以使用 Result
属性 获得每个任务的结果(再次假设您的方法 return Task<T>
:
Letter msg1 = msgTask1.Result;
SMS msg2 = msgTask2.Result;
当然,这一切都假设WaitForLetter
和WaitForSMS
的实现是独立的,不会互相阻塞。
如果您只想等待 任何 个任务完成,您可以使用 `Task.WaitAny' 来达到相同的目的。此 return 是已完成任务的索引,因此您知道哪一个已完成。
while(true) {
Task<Letter> msgTask1 = WaitForLetter();
Task<SMS> msgTask2 = WaitForSMS();
var finishedTask = Task.WaitAny(msgTask1, msgTask2);
}
我认为您最好的选择是使用 Microsoft 的 Reactive Framework (NuGet "Rx-Main")。它与 Tasks 配合得很好。
这是您需要的代码:
var subscription1 =
Observable
.FromAsync(WaitForLetter)
.Repeat()
.Subscribe(msg1 =>
{
//read msg1 and reply.
});
var subscription2 =
Observable
.FromAsync(WaitForSMS)
.Repeat()
.Subscribe(msg2 =>
{
//read msg2 and reply
});
两者 运行 彼此独立并且 运行 异步。
要阻止他们运行宁只需这样做:
subscription1.Dispose();
subscription2.Dispose();
如果你真的想让它们运行像一个事件循环,消息都进入同一个线程,相互穿插,那么你可以这样做:
var eventLoopScheduler = new EventLoopScheduler();
var subscription1 =
Observable
.FromAsync(WaitForLetter)
.Repeat()
.ObserveOn(eventLoopScheduler)
.Subscribe(msg1 =>
{
//read msg1 and reply.
});
var subscription2 =
Observable
.FromAsync(WaitForSMS)
.Repeat()
.ObserveOn(eventLoopScheduler)
.Subscribe(msg2 =>
{
//read msg2 and reply
});
你还有一点 clean-up,但这可以很好地处理:
var subscriptions = new CompositeDisposable(
subscription1,
subscription2,
eventLoopScheduler);
//then later
subscriptions.Dispose();
如何同时等待两个或更多的东西(不同类型)?就像在事件循环中一样:
while(true) {
Letter msg1 = await WaitForLetter();
//read msg1 and reply.
SMS msg2 = await WaitForSMS();
//read msg2 and reply
}
这看起来不对。两条消息最终会互相阻塞吗?
目前,您的代码将依次等待每个方法完成。如果你想发送每条消息然后在最后等待两者,你可以使用 Task.WaitAll
方法(假设你的方法 return 一个 Task<T>
对象。
while(true) {
Task<Letter> msgTask1 = WaitForLetter();
Task<SMS> msgTask2 = WaitForSMS();
Task.WaitAll(msgTask1, msgTask2);
}
然后您可以使用 Result
属性 获得每个任务的结果(再次假设您的方法 return Task<T>
:
Letter msg1 = msgTask1.Result;
SMS msg2 = msgTask2.Result;
当然,这一切都假设WaitForLetter
和WaitForSMS
的实现是独立的,不会互相阻塞。
如果您只想等待 任何 个任务完成,您可以使用 `Task.WaitAny' 来达到相同的目的。此 return 是已完成任务的索引,因此您知道哪一个已完成。
while(true) {
Task<Letter> msgTask1 = WaitForLetter();
Task<SMS> msgTask2 = WaitForSMS();
var finishedTask = Task.WaitAny(msgTask1, msgTask2);
}
我认为您最好的选择是使用 Microsoft 的 Reactive Framework (NuGet "Rx-Main")。它与 Tasks 配合得很好。
这是您需要的代码:
var subscription1 =
Observable
.FromAsync(WaitForLetter)
.Repeat()
.Subscribe(msg1 =>
{
//read msg1 and reply.
});
var subscription2 =
Observable
.FromAsync(WaitForSMS)
.Repeat()
.Subscribe(msg2 =>
{
//read msg2 and reply
});
两者 运行 彼此独立并且 运行 异步。
要阻止他们运行宁只需这样做:
subscription1.Dispose();
subscription2.Dispose();
如果你真的想让它们运行像一个事件循环,消息都进入同一个线程,相互穿插,那么你可以这样做:
var eventLoopScheduler = new EventLoopScheduler();
var subscription1 =
Observable
.FromAsync(WaitForLetter)
.Repeat()
.ObserveOn(eventLoopScheduler)
.Subscribe(msg1 =>
{
//read msg1 and reply.
});
var subscription2 =
Observable
.FromAsync(WaitForSMS)
.Repeat()
.ObserveOn(eventLoopScheduler)
.Subscribe(msg2 =>
{
//read msg2 and reply
});
你还有一点 clean-up,但这可以很好地处理:
var subscriptions = new CompositeDisposable(
subscription1,
subscription2,
eventLoopScheduler);
//then later
subscriptions.Dispose();