Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在c中等待事件被处理#_C#_.net_Multithreading_Events - Fatal编程技术网

C# 如何在c中等待事件被处理#

C# 如何在c中等待事件被处理#,c#,.net,multithreading,events,C#,.net,Multithreading,Events,假设我们有这样的代码: public class MyProcess { private Process _process; public event EventHandler OnFinish; public MyProcess(string pathToExe) { _process = new Process(); _process.StartInfo.FileName = pathToExe; } pub

假设我们有这样的代码:

public class MyProcess
{
    private Process _process;
    public event EventHandler OnFinish;
    public MyProcess(string pathToExe)
    {
         _process = new Process();
         _process.StartInfo.FileName = pathToExe;
    }
    public int Start()
    {
         _process.Exited += _processExited;
         _process.Start();
         return _process.Id;
    }
    public void Stop()
    {
         _process.Stop();
    }
    private void _processExited(object sender, EventArgs e)
    {
         OnFinish?.Invoke();
    }
}

public class MyProgram
{
    private static int stoppedProcs = 0;

    public static void Main(string[] args)
    {
         var proc = new MyProcess("foo.exe");
         proc.OnFinish += proc_OnFinish;
         proc.Start();
         proc.Stop();
         //Wait here to display 1 instead of 0
         Console.WriteLine(stoppedProcs);
    }

    private static void proc_OnFinish(object sender, EventArgs e)
    {
         stoppedProcs++;
    }
}

我创建并启动流程。然后我想停止它,只有在我处理完事件后才继续。问题是我自己并没有像操作系统那样调用事件。如何理解事件处理程序已完成?

假设您希望同步等待(阻止当前线程),只需通过类公开该方法即可

扩展提及
任务
等待
内容的答案

如果要将等待转换为异步流,可以将退出的
事件与
TaskCompletionSource
组合,如下所示:

public static class ProcessExtension
{
    public static Task WaitForExitAsync(this Process proc, Action callback)
    {
        return new WaitForExitExt(proc, callback).WaitTask;
    }

    class WaitForExitExt
    {
        private TaskCompletionSource<int> _tcs;
        private Action _callback;

        public WaitForExitExt(Process proc, Action callback)
        {
            _callback = callback;
            proc.EnableRaisingEvents = true;

            _tcs = new TaskCompletionSource<int>();

            if (proc.HasExited)
            {
                _tcs.TrySetResult(proc.ExitCode);
            }
            else
            {
                proc.Exited += OnProcessExited;

                // Process already exited by the time the handler was attached.
                if (proc.HasExited)
                {
                    proc.Exited -= OnProcessExited;
                    _tcs.TrySetResult(proc.ExitCode);
                }
            }
        }

        public Task WaitTask => _tcs.Task;

        private void OnProcessExited(object sender, EventArgs e)
        {
            var proc = (Process)sender;
            proc.Exited -= OnProcessExited;

            _callback();

            _tcs.TrySetResult(proc.ExitCode);
        }
    }
}
输出为:

Exited
Task finished

谢谢大家回答我的问题。 @Fildor建议使用
ManualResetEvent

public class MyProgram
{
private static int stoppedProcs = 0;
private static ManualResetEvent mre = new ManualResetEvent(false);
public static void Main(string[] args)
{
     var proc = new MyProcess("foo.exe");
     proc.OnFinish += proc_OnFinish;
     proc.Start();
     proc.Stop();
     //Wait here to display 1 instead of 0
     mre.WaitOne();
     mre.Reset();
     Console.WriteLine(stoppedProcs);
}

private static void proc_OnFinish(object sender, EventArgs e)
{
     stoppedProcs++;
     mre.Set();
}
}

是您的
过程
系统.诊断.过程
?我在
System.Diagnostics.Process
中未找到任何
Stop
。请查看事件模式,或者您是否希望坚持事件模式。不过,您也可以切换到基于任务的异步()。@LouisGo是的。我错了,我用Kill()@LouisGo我不明白我能在这里等待什么。我不调用异步方法。我杀死一个进程,操作系统发出信号,表示进程退出,然后处理程序退出invoked@Alexander抱歉,费尔多的建议更适合您的情况,我将删除我的评论以避免混淆。此解决方案可能很简单,但它是否可靠?如果在
mre.WaitOne()
行之前调用中的
proc\u OnFinish
处理程序,会发生什么情况?“这能保证永远不会发生吗?”西奥多·祖利亚斯,问得好。据我所知,这并不重要。如果在
mre.WaitOne()
之前调用处理程序并调用
mre.Set()
则主线程不会被阻止。你说得对,我已经忘记了这一点!因此,如果
proc\u OnFinish
只运行一次,则没有竞争条件。行
stoppedProcs++
表明情况可能并非如此!顺便说一句,看看线程安全增量的方法。
Exited
Task finished
public class MyProgram
{
private static int stoppedProcs = 0;
private static ManualResetEvent mre = new ManualResetEvent(false);
public static void Main(string[] args)
{
     var proc = new MyProcess("foo.exe");
     proc.OnFinish += proc_OnFinish;
     proc.Start();
     proc.Stop();
     //Wait here to display 1 instead of 0
     mre.WaitOne();
     mre.Reset();
     Console.WriteLine(stoppedProcs);
}

private static void proc_OnFinish(object sender, EventArgs e)
{
     stoppedProcs++;
     mre.Set();
}
}