Beenden eines blockierten Threads in einer C# .NET-Desktop-AppC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Beenden eines blockierten Threads in einer C# .NET-Desktop-App

Post by Anonymous »

Gibt es in einer C#-Desktopanwendung mit .NET eine Möglichkeit, einen Thread zu beenden, der aufgrund eines Problems in einer externen Bibliothek hängen geblieben ist? Denn wenn wir den Thread mit Task.Run() erstellen, haben wir keine Kontrolle, ihn zu stoppen, und wenn wir ihn mit einem neuen Thread erstellen, haben wir Thread.Abort(), aber in der Dokumentation heißt es, dass er „veraltet“ und „nicht unterstützt“ ist.
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)
{
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post