本文介绍了System.Diagnostic.Process的线程池问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ThreadPool对名为RunScripts的方法进行多次调用.线程数由要运行的sql脚本文件数维护.如果有4个要运行的sqlscript,则我对ThreadPool.QueueUserWorkItem进行了4次调用.在RunScripts方法中,我正在使用System.Diagnostic.Process运行sql脚本,如代码所示.该流程具有两个事件处理程序,分别是OutPutDataReceived和ErrorDataRecieved.在这两个事件中,我只是在控制台中打印消息.我已经设置了ThreadPool.SetMinThreads = 4和ThreadPool.SetMaxThreads = 10.

在代码中,我的进程完成工作后,就立即调用了executorProcess.CancelOutputRead()和executorProcess.CancelErrorRead().如果我没有记错的话,那么只有在有任何标准output/error的情况下调用两个事件之后,程序执行才会到达这些行.我的脚本在3或4秒钟内完成执行.我的问题是没有为每个线程调用OutputDataReceived和ErrorDataReceived事件.异步读取在调用两个事件之前被取消.但是,如果我增加MinThreads和MasThreads,则在调试点到达CancelOutputRead()和CancelErrorRead()之前调用这两个事件.
当我从代码中删除executorProcess.CancelOutputRead()和executorProcess.CancelErrorRead()时,每个标准输出和错误都会被打印出来.我不确定为什么线程数较少时为什么它不起作用.

I am using ThreadPool to make multiple calls to a method called RunScripts. Number of threads are maintained by a count of number of sql scriptfile to run. If there are 4 sqlscripts to run then I make call to ThreadPool.QueueUserWorkItem 4 times and son on. In the RunScripts method, I am using System.Diagnostic.Process to run the sql scripts as shown is the code. The Process has two event handlers namely OutPutDataReceived and ErrorDataRecieved. In both of the events, I am simply printing the message in console. I have set the ThreadPool.SetMinThreads=4 and ThreadPool.SetMaxThreads=10.

In the code, I have called executorProcess.CancelOutputRead() and executorProcess.CancelErrorRead() as soon as my process finish the work. If I am not wrong the program execution reach these lines only after the two events are called if there are any standard output/error . My scripts finish execution within 3 or 4 seconds. My problem here is OutputDataReceived and ErrorDataReceived events are not called for every threads. Asynchronous reads are being cancelled before the two events are invoked.However, if I increase the MinThreads and MasThreads then the two events are called before the debug point reach CancelOutputRead() and CancelErrorRead().

when I removed the executorProcess.CancelOutputRead() and executorProcess.CancelErrorRead() from the code then every standard ouput and error are being printed. I am not sure why it is not working when there are less number of threads.

Private void RunScripts()
{

      // Start SQLCMD process.
                ProcessStartInfo psi = new ProcessStartInfo();
                psi.FileName = "SQLCMD.EXE";
                string args = "-S " + this.Server;
                if (string.IsNullOrEmpty(this.UserName)) args += " -E";
                else args += " -U " + this.UserName;
                if (!string.IsNullOrEmpty(scriptFile.Database))
                    args += " -d " + scriptFile.Database;
                if (string.IsNullOrEmpty(this.Password))
                    args += " -i " + scriptFilePath;
                else
                    args += " -P " + this.Password + " -i " + scriptFilePath;
                psi.Arguments = args;
                psi.RedirectStandardOutput = true;
                psi.RedirectStandardError = true;
                psi.UseShellExecute = false;

                using (Process executorProcess = Process.Start(psi))
                {
                    executorProcess.EnableRaisingEvents = true;
                    executorProcess.OutputDataReceived +=
                        new DataReceivedEventHandler(
                            this.executorProcess_DataReceived);
                    executorProcess.ErrorDataReceived +=
                        new DataReceivedEventHandler(executorProcess_ErrorDataReceived);

                    executorProcess.BeginOutputReadLine();
                    executorProcess.BeginErrorReadLine();
                    bool exited = false;
                    while (!exited)
                    {
                        exited = executorProcess.WaitForExit(60000);
                        if (!exited && this.StopSignal)
                        {
                            try { executorProcess.Kill(); }
                            catch { }
                        }
                    }
                    try
                    {
                        executorProcess.CancelOutputRead();
                        executorProcess.CancelErrorRead();
                    }
                    catch { }
}


        void executorProcess_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
          Console.WriteLine(e.Data);
        }

       private void executorProcess_DataReceived(object sender,
            DataReceivedEventArgs e)
        {
            Console.WriteLine(e.Data);
        }

推荐答案



这篇关于System.Diagnostic.Process的线程池问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-28 10:42
查看更多