C# 回调/事件处理程序在函数的第一次迭代后停止工作

C# 回调/事件处理程序在函数的第一次迭代后停止工作,c#,callback,C#,Callback,首先,很抱歉我使用了错误的术语,因为我不是一个程序员,所有这些编程对我来说都是很新的 我有一个不断检查布尔值的循环: class Program { static cliparser connectionstatus = new cliparser(); static void Main(string[] args) { Console.WriteLine("MAIN()__ START"); while (true)

首先,很抱歉我使用了错误的术语,因为我不是一个程序员,所有这些编程对我来说都是很新的

我有一个不断检查布尔值的循环:

class Program
{
    static cliparser connectionstatus = new cliparser();

    static void Main(string[] args)
    {
        Console.WriteLine("MAIN()__ START");

        while (true)
        {
            Console.WriteLine("MAIN()__WHILE, USERS LOGGED IN");

            if (connectionstatus.Disconnected())
            {
                Console.WriteLine("MAIN()__VPN DISCONNECTED");
            }
            Console.WriteLine("MAIN()__SLEEP 3s START");
            Console.WriteLine("MAIN()__SLEEP 3s END" + Environment.NewLine);
        }
    }
}
然后是另一段代码,它实际检查bool的值:

class cliparser
{
    private bool DisconnectedValue;

    static ProcessStartInfo vpncliStartInfo = new ProcessStartInfo()
    {
        FileName = Path.Combine(parent, "vpncli.exe"),
        RedirectStandardOutput = true,
        RedirectStandardError = false,
        UseShellExecute = false,
        CreateNoWindow = true,
        Arguments = "status"
    };

    private Process vpncliProcess = new Process() {StartInfo = vpncliStartInfo,};

    public cliparser()
    {
        vpncliProcess.ErrorDataReceived += vpncli_Error;            //init callbacks
        vpncliProcess.OutputDataReceived += vpncli_DataReceived;    //init callbacks
        vpncliProcess.EnableRaisingEvents = true;
    }

    public bool Disconnected()
    {
        Console.WriteLine("Disconnected()__BEGIN");
        Console.WriteLine("Disconnected()__DISCO-BOOL: " + DisconnectedValue.ToString());

        vpncliProcess.Start();
        vpncliProcess.BeginOutputReadLine();
        Console.WriteLine("Disconnected()__END");
        return DisconnectedValue;
    }

    private void vpncli_DataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data != null && e.Data.Contains("Disconnected"))
        {
            DisconnectedValue = true;
            Console.WriteLine("vpncli_DataReceived__disconnected, SET DISCO-BOOL TO: " + DisconnectedValue.ToString());
            vpncliProcess.CancelOutputRead();
            Console.WriteLine("vpncli_DataReceived__disconnected E: " + e.Data);
        }       
    }
}
方法Disconnected的第一次调用顺利完成

然后while循环第二次启动Disconnected方法。但是现在vpncli_DataReceived回调不再工作,事件也不会引发。我不知道这是什么原因

我知道vpncliProcess.BeginOutputReadLine流是活动的,因为在第三个循环中,我得到一个异常,即BeginOutputReadLine操作已经启动。请注意,我正在回调中发出CancelOutPutRead

长话短说:

为什么第一个**断开连接的方法结束后回调不起作用**

我在程序中添加了一个事件顺序日志,也许这有助于更好地理解问题:

MAIN()__ START
MAIN()__WHILE, USERS LOGGED IN
Disconnected()__BEGIN
Disconnected()__DISCO-BOOL: False
vpncli_DataReceived__disconnected, SET DISCO-BOOL TO: True
vpncli_DataReceived__disconnected E:   >> state: Disconnected
Disconnected()__END
MAIN()__VPN DISCONNECTED
MAIN()__SLEEP 3s START
MAIN()__SLEEP 3s END

MAIN()__WHILE, USERS LOGGED IN
Disconnected()__BEGIN
Disconnected()__DISCO-BOOL: True
Disconnected()__END
MAIN()__VPN DISCONNECTED
MAIN()__SLEEP 3s START
MAIN()__SLEEP 3s END

MAIN()__WHILE, USERS LOGGED IN
Disconnected()__BEGIN
Disconnected()__DISCO-BOOL: True

有什么想法或建议吗?谢谢

首先,您应该检查您的代码,使其异步或同步,但不要将其混合。虽然您有声称睡眠3秒的输出语句,但代码中没有相应的睡眠调用。while循环正在以最快的速度运行。正如@aush所说,混合使用同步和异步代码非常容易出错,并且对竞争条件非常敏感。我不相信您发布的确切代码能够产生您描述的确切输出。断开连接的方法将返回得如此之快,以至于在断开连接的方法返回到主循环且主循环写入睡眠消息之前,进程极不可能启动、输出一些文本并让事件处理程序接收文本以显示输出。在任何情况下,如果没有自包含的代码示例,回答这个问题是不可能的。我会说,一般来说,我不会尝试重用流程对象,但这是否是真正的问题,我不能说。似乎我不是唯一一个有问题的人。似乎每次调用断开连接的方法时,我都必须生成一个新进程。。。无法重用现有流程。