【问题标题】:Awaiting Process.Start with Observable等待过程。从 Observable 开始
【发布时间】:2018-07-03 22:45:27
【问题描述】:

我创建了以下代码。我以为它会起作用,但事实并非如此。 await 无限期地挂在那里(永远不会调用 Exit 事件)。

我在没有参数的情况下调用“ping”,所以它几乎会立即结束。

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 使其工作?

【问题讨论】:

    标签: c# .net async-await system.reactive


    【解决方案1】:

    你在这里有一个竞争条件。来自this RX repro thread的引用:

    FirstAsync 返回一个冷的 observable。直到你订阅 它或等待您将收到消息。

    TaskCompletionSource(在此使用可能更合适,IMO)不同,FirstAsync返回的 observable 不会“缓存”在您激活 之前发生的事件通过等待订阅。因此,process.Exited 事件在await obs.FirstAsync() 之前触发,因此.NET 启动代码块在由Main 返回的任务上。

    以下将按预期工作(您需要添加using System.Reactive.Threading.Tasks):

    var task = obs.FirstAsync().ToTask();
    
    var started = process.Start();
    if (!started)
    {
        throw new InvalidOperationException("Could not start process: " + process);
    }
    
    await task;
    

    在这里,我们通过将其转换为 Task 来激活 observable 订阅,然后再开始该过程。

    如果对Observable.FromEventPattern 之类的内容感兴趣,但对TaskCompletionSource 感兴趣,请查看this Q/A

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-17
      • 1970-01-01
      • 1970-01-01
      • 2018-10-06
      • 2014-01-31
      • 1970-01-01
      • 2018-08-06
      相关资源
      最近更新 更多