Ich habe über die Option nachgedacht, die problematischen Vorgänge in einen externen Prozess in einer separaten .exe-Datei zu verschieben, aber in diesem Fall würde die Kommunikation mit der Hauptanwendung äußerst komplex werden, also suche ich nach einer Möglichkeit - wenn möglich - alles mit separaten Threads innerhalb der Hauptanwendung zu erledigen.
Mit Task.Run() erstelle ich 4 Threads, die die Dateien in einem bestimmten Ordner durchlaufen, und die ProcessSingleFile-Methode verwendet Dutzende verschiedener externer Bibliotheken, um den Text aus jeder Datei zu lesen.
Alles funktioniert gut, aber wenn beim Lesen einer Datei eine externe Bibliothek hängt, läuft der Thread nach dem Lesen aller Dateien weiter und läuft weiter verbraucht CPU-Zeit, was ein großes Problem darstellt.
Hier ist ein Beispielcode, den ich gerade verwende:
Code: Select all
protected void GetFilesText(string folderPath, CancellationToken token)
{
token.ThrowIfCancellationRequested();
lock (_timedOutTasksLock)
{
_timedOutTasks.Clear();
}
int processedCount = 0;
object lockObj = new object();
var options = new ParallelOptions
{
MaxDegreeOfParallelism = 4,
CancellationToken = token
};
try
{
Parallel.ForEach(filesToProcess, options, (filePath, state) =>
{
if (token.IsCancellationRequested)
{
state.Break();
return;
}
try
{
var fileTask = Task.Run(() =>
{
ProcessSingleFile(filePath, isReadFolder, token);
}, token);
bool completed = fileTask.Wait(TimeSpan.FromSeconds(15));
if (!completed)
{
LogReadingError(filePath, "Timeout after 15s - file skipped");
lock (_timedOutTasksLock)
{
_timedOutTasks.Add((fileTask, filePath));
}
}
}
catch (OperationCanceledException)
{
}
catch (AggregateException ae)
{
LogReadingError(filePath, ae.InnerException?.Message ?? ae.Message);
}
catch (Exception e)
{
LogReadingError(filePath, e.Message);
}
});
}
catch (OperationCanceledException)
{
}
}
Mobile version