У меня есть следующий код в классе MessageSaver.cs, который отвечает за сохранение сообщения в текстовый файл. В любом приложении, использующем MessageSaver.dll, я пытаюсь обрабатывать запросы на сохранение сообщений, когда приложение начинает завершать работу.
Эта dll может использоваться приложением Winforms, приложением WPF, приложением ASP.Net или консольным приложением с помощью следующего кода.
var filePath = "c\\abc\\xyz\\efg\\msg.txt";
var content = "some message";
MessageSaver saver = new MessageSaver();
await saver.SaveMessageAsync(filePath, content);
Прямо сейчас я реализовал некоторый код для корректной обработки этого, как описано ниже.
Метод Shutdown будет вызываться кодом приложения с использованием MessageSaver.dll в соответствующем событии завершения работы/выхода процесса.
//in the shutdown event of the application, this code needs to be there
MessageSaver saver = new MessageSaver();
saver.Shutdown();
Я рассматриваю это так: когда приложение инициирует завершение работы, тогда может быть один или несколько запросов на сохранение сообщений; некоторые из этих запросов не достигли бы стадии FileStream в методе SaveMessageAsync, тогда как другие достигли бы. Для тех запросов, которые не достигли стадии FileStream, выход из метода SaveMessageAsync будет зависеть от статуса _shutdownTokenSource. Для запросов, которые достигли стадии FileStream или прошли ее, WriteLineAsync предотвращается путем просмотра статуса _shutdownTokenSource.
Но что происходит с запросами, прошедшими стадию FileStream и начавшими запись, т. е. ожидание sw.WriteLineAsync(content) достигнуто? Я не знаю, как обрабатывать такие запросы при завершении работы. Насколько я понимаю, такие запросы будут ожидаться до завершения работы приложения, и поэтому мне не нужно беспокоиться о неудаленных дескрипторах файлов для этих запросов.
public class MessageSaver {
private readonly CancellationTokenSource _shutdownTokenSource = new();
private static readonly object _shutdownLocker = new();
public void Shutdown() {
lock(_shutdownLocker) {
_shutdownTokenSource.Cancel();
}
}
public async Task SaveMessageAsync(string filePath, string content, bool append = true) {
//cancel all new requests to save a message if the application is shutting down
if (_shutdownTokenSource.IsCancellationRequested) {
// Optionally, save to a fallback mechanism or discard the message
return;
}
using(FileStream stream = new FileStream(filePath, append ? FileMode.Append: FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
using(StreamWriter sw = new StreamWriter(stream)) {
//do not save if shutdown is occurring
if (_shutdownTokenSource.IsCancellationRequested) {
await sw.WriteLineAsync(content);
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... n-net-apps