C# 在一个循环中等待两件事?
我怎么能同时等待两件或两件以上的事情(不同类型的)?就像在事件循环中一样:C# 在一个循环中等待两件事?,c#,asynchronous,task,C#,Asynchronous,Task,我怎么能同时等待两件或两件以上的事情(不同类型的)?就像在事件循环中一样: while(true) { Letter msg1 = await WaitForLetter(); //read msg1 and reply. SMS msg2 = await WaitForSMS(); //read msg2 and reply } 这看起来不对。这两条消息最终会互相阻塞?目前,您的代码将依次等待每个方法完成。如果希望发送每条消息,然后在最后等待这两条消息,则可以
while(true) {
Letter msg1 = await WaitForLetter();
//read msg1 and reply.
SMS msg2 = await WaitForSMS();
//read msg2 and reply
}
这看起来不对。这两条消息最终会互相阻塞?目前,您的代码将依次等待每个方法完成。如果希望发送每条消息,然后在最后等待这两条消息,则可以使用该方法(假设您的方法返回
Task
对象)
while(true) {
Task<Letter> msgTask1 = WaitForLetter();
Task<SMS> msgTask2 = WaitForSMS();
Task.WaitAll(msgTask1, msgTask2);
}
当然,这一切都假设WaitForLetter
和WaitForSMS
的实现是独立的,不会相互阻塞
如果您只想等待任何任务完成,您可以使用to to More the end。这将返回已完成任务的索引,以便您知道哪个任务已完成
while(true) {
Task<Letter> msgTask1 = WaitForLetter();
Task<SMS> msgTask2 = WaitForSMS();
var finishedTask = Task.WaitAny(msgTask1, msgTask2);
}
while(true){
任务msgTask1=WaitForLetter();
任务msgTask2=WaitForSMS();
var finishedTask=Task.WaitAny(msgTask1,msgTask2);
}
我认为您最好的选择是使用Microsoft的反应式框架(NuGet“Rx Main”)。它可以很好地处理任务
以下是您需要的代码:
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
});
您需要进行更多的清理,但这可以通过以下方式很好地处理:
var subscriptions = new CompositeDisposable(
subscription1,
subscription2,
eventLoopScheduler);
//then later
subscriptions.Dispose();
为什么你需要while(真的)在他的代码中,可能有更多的代码他没有发布。相关部分是
WaitAll
。但问题是,我可能一小时收到一条短信,但一个月只有一封信。所以我不能等所有的。我想等任何一条。我不确定如何做,当任务类型不同时,etc@someoneelse那你真走运有一种方法可以做到这一点,等待任何任务完成后再继续。你必须在任务完成之前添加一些验证,并确保不会遇到问题,但它是可用的。谢谢。task.WaitAny对不同类型的任务有效吗?例如,我可以将一个任务和一个任务放入任务[]数组?我想我必须创建一个任务数组,然后再把它转换成正确的类型(我是C++程序员,所以不太熟悉C变量数组)。您可以使用WaitAll
或WaitAny
,但除非每条短信都有一个字母,否则为什么要将它们放在同一个无限循环中?您可以将它们放在两个while循环中…无限循环中如果这里真的需要事件循环,那么RX确实需要并依靠代码解决方案来使用。@vittor-对不起,您能解释一下吗明白你所说的“需要并依靠代码解决方案来使用”是什么意思这看起来很干净。C语言世界里的人比C++更接近于异步。我有点嫉妒。我们最终会在下一个C++标准中等待和协同工作。很少有C++程序员知道如何使用等待。所以这就是为什么我最后问了如何使用C等待。我希望我们能得到一些好的框架。AR到LINQ和RX,在C++中建立在协程序的顶部。但是我们可能需要等待几年。@ Enigmativity是一个错误:“代码代码很好,很精益”。
var subscriptions = new CompositeDisposable(
subscription1,
subscription2,
eventLoopScheduler);
//then later
subscriptions.Dispose();