Sto scrivendo un programma che sposta file csv da una cartella "coda" a una cartella "elaborazione", quindi viene avviato un processo di terze parti chiamato import.exe prendendo il percorso del file csv come un argomento. Import.exe è un'attività a esecuzione prolungata.Esecuzione di processi esterni in modo asincrono in un servizio Windows
Ho bisogno che il programma continui a funzionare e controlla la coda per i nuovi file. Per questo motivo ho scelto un'applicazione di servizio Windows poiché sarà di lunga durata.
Il mio problema è che sono sopraffatto dalle opzioni e non riesco a capire se dovrei affrontare questo problema con background threads o parallel programming, o molto probabilmente una combinazione di entrambi.
Finora ho questo codice che è appena in esecuzione in modo sincrono. Vedrete rapidamente che al momento, sto semplicemente licenziando i processi senza comunque gestire o controllare il completamento. Ho commentato process.WaitForExit() poiché ovviamente questa è una chiamata bloccante.
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
}
}
}
Ho anche provato a creare una serie di attività e a eseguirle in modo asincrono. Ma alla fine dovevo ancora chiamare Task.WaitAll() prima che potessi leggere il risultato. Quindi, anche se uno finisce presto, deve attendere l'attività più lunga.
Penso di aver bisogno di provare il ciclo attraverso la creazione di processi in modo asincrono, magari usando le attività, ma non capisco come farlo come un processo in background, in modo da poter mantenere il timer del servizio di controllo per il numero di processi se necessario per creare di più.
Accanto a '' Task.WaitAll() '', v'è anche '' Task.WaitAny() '' che potrebbe aiutare con il problema che hai descritto nella domanda. Il progetto generale che prenderei in considerazione per primo sarebbe che ogni task svolga un solo lavoro, inclusa la generazione di un'istanza di "import.exe" e in attesa che venga eseguita. Con il watcher del file system (ad esempio), rilevi le modifiche nella cartella e per ogni modifica (nuovo file) pianifichi un'attività. Il timer non è davvero essenziale qui a meno che tu non voglia limitare l'elaborazione e controllare solo gli intervalli invece di reagire immediatamente alle modifiche. – BitTickler
Un problema da correggere: considera cosa succede se qualche altro software utilizza una procedura denominata "import.exe". (Piuttosto che contare il numero di processi con un determinato nome, dovresti tenere traccia dei processi specifici che hai lanciato.) –
Thats @HarryJohnston.Con la risposta data non credo di aver bisogno di tenere traccia del numero di processi in esecuzione più. Se avessi continuato con il codice nella mia domanda, terrei una lista degli ID di processo. Assicurarsi di rimuoverli dall'elenco quando il processo è terminato. – SeanOB