我正在编写一个程序,将csv文件从“队列”文件夹移动到“处理”文件夹,然后启动名为import.exe的第三方进程,并将csv文件路径作为参数传递。Import.exe是一个长时间运行的任务。
我需要程序继续运行并检查队列中是否有新文件。出于这个原因,我选择了Windows服务应用程序,因为它将长时间运行。
我的问题是,我被选项所压倒,无法理解我是否应该使用后台线程或并行编程来解决这个问题,或者最可能是两者的结合。
到目前为止,我只是同步运行这段代码。您很快就会看到,目前我只是疯狂地启动进程,没有任何管理或检查完成的方式。我已经注释掉了process.WaitForExit(),因为这显然是一个阻塞调用。
我也尝试创建任务数组,并异步运行它们。但最后我仍然需要调用Task.WaitAll()才能读取结果。因此,即使一个任务早已完成,它也必须等待运行时间最长的任务。
我认为我需要尝试通过循环异步创建进程,可能使用任务,但我不知道如何将其作为后台进程执行,以便在需要创建更多进程时保持服务计时器检查。
我需要程序继续运行并检查队列中是否有新文件。出于这个原因,我选择了Windows服务应用程序,因为它将长时间运行。
我的问题是,我被选项所压倒,无法理解我是否应该使用后台线程或并行编程来解决这个问题,或者最可能是两者的结合。
到目前为止,我只是同步运行这段代码。您很快就会看到,目前我只是疯狂地启动进程,没有任何管理或检查完成的方式。我已经注释掉了process.WaitForExit(),因为这显然是一个阻塞调用。
public int maxConcurrentProcesses = 10;
protected override void OnStart(string[] args)
{
// Set up a timer to trigger every minute.
System.Timers.Timer timer = new System.Timers.Timer(60000);
timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
timer.Start();
}
private void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
// How many instances of import.exe are running?
Process[] importProcesses = Process.GetProcessesByName("import");
int countRunning = importProcesses.Count();
// If there are less than maxConcurrentProcesses, create as many as needed to reach maxConcurrentProcesses
if (countRunning < maxConcurrentProcesses)
{
int processesToStart = maxConcurrentProcesses - countRunning;
for (int i = 0; i < processesToStart; i++)
{
FireOffImport();
}
}
}
private void FireOffImport()
{
// Get the first file returned from the Queue folder
string filePathSource = GetNextCSVInQueue();
if (filePathSource != "")
{
// …
// commandArguments = create our arguments here
// …
// Move the file to processing folder here
// …
// Give a new process the import tool location and arguments
ProcessStartInfo startInfo = new ProcessStartInfo(importLocation + "\\import.exe", commandArguments);
try
{
Process process = Process.Start(startInfo);
// process.WaitForExit(20000);
// If the process has exited, there will be 4 csv files created in the same directory as the file.
}
catch (Exception ex)
{
// Deal with exception here
}
}
}
我也尝试创建任务数组,并异步运行它们。但最后我仍然需要调用Task.WaitAll()才能读取结果。因此,即使一个任务早已完成,它也必须等待运行时间最长的任务。
我认为我需要尝试通过循环异步创建进程,可能使用任务,但我不知道如何将其作为后台进程执行,以便在需要创建更多进程时保持服务计时器检查。
Task.WaitAll()
之外,还有Task.WaitAny()
可以帮助您解决问题。我首先考虑的一般设计是,每个任务都只做一件事情,包括生成import.exe
实例并等待其完成。使用文件系统监视器(例如),您可以检测文件夹中的更改,并为每个更改(新文件)安排一个任务。计时器在这里并不是真正必要的,除非您想限制处理并仅在间隔内检查而不是立即响应更改。 - BitTickler