问题描述
我正在使用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的线程池问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!