C# 等待过程。从可观察开始
我创建了以下代码。我原以为它会起作用,但事实并非如此。等待无限期地挂起(从不调用退出事件) 我打电话给“ping”,没有任何争论,所以它几乎会立即结束C# 等待过程。从可观察开始,c#,.net,async-await,system.reactive,C#,.net,Async Await,System.reactive,我创建了以下代码。我原以为它会起作用,但事实并非如此。等待无限期地挂起(从不调用退出事件) 我打电话给“ping”,没有任何争论,所以它几乎会立即结束 using System; using System.Diagnostics; using System.Reactive.Linq; using System.Threading.Tasks; namespace ConsoleApp3 { class Program { static async Task M
using System;
using System.Diagnostics;
using System.Reactive.Linq;
using System.Threading.Tasks;
namespace ConsoleApp3
{
class Program
{
static async Task Main(string[] args)
{
var process = new Process
{
StartInfo =
{
FileName = "ping",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
},
EnableRaisingEvents = true
};
var obs = Observable.FromEventPattern(handler => process.Exited += handler, handler => process.Exited -= handler);
var started = process.Start();
if (!started)
{
throw new InvalidOperationException("Could not start process: " + process);
}
await obs.FirstAsync();
}
}
}
如何使用IObservable使其工作 这里有一个比赛条件。引自: FirstAsync返回一个冷的可观察值。直到你订阅 等待或等待您收到消息 与
TaskCompletionSource
(IMO在这里使用它可能更合适)不同,FirstAsync
返回的可观察对象不会通过等待来“缓存”激活订阅之前发生的事件。因此,process.Exited
事件在wait obs.FirstAsync()
之前被触发,因此,Main
返回的任务上的.NET启动代码块被触发
以下操作将按预期工作(您需要使用System.Responsive.Threading.Tasks添加):
在这里,我们通过在启动流程之前将其转换为任务来激活可观察订阅
如果对类似于可观察的.FromEventPattern
的内容感兴趣,但对于任务完成源代码
,请检查
var task = obs.FirstAsync().ToTask();
var started = process.Start();
if (!started)
{
throw new InvalidOperationException("Could not start process: " + process);
}
await task;