Я пытаюсь написать в файл журнала асинхронно в C#. У меня есть этот код регистратора ниже и куча тестов, чтобы убедиться, что он работает правильно. Каждый раз, когда я запускаю тесты, некоторые из них случайно не всегда всегда всегда с ошибкой, в которой указано, что метод очистки не может получить доступ к файлу: testCleanup Метод Tests.logger_test.cleanup через исключение. System.UnauthorizedAccessException: доступ к пути 'C: \ \ log_test.log' отрицается .. или какое -то изменение журнала было только частично записано в файл журнала.
Класс журнала:
public static class Logger
{
public enum Severity
{
CRITICAL,
ERROR,
INFORMATION
}
public static async Task LogException(Exception ex, Severity severity, string path = "")
{
SemaphoreSlim gate = new SemaphoreSlim(1);
if (path == "")
path = "ErrorLog.log";
string logMessage = $"{severity} {DateTime.Now}: {ex.Message} - {(ex.InnerException != null ? ex.InnerException.Message : "")}";
await gate.WaitAsync();
try
{
using (var sw = File.AppendText(path))
sw.WriteLine(logMessage);
}
finally
{
gate.Release();
}
}
}
< /code>
tests: < /p>
namespace Tests;
[TestClass]
public class Logger_Test
{
private const string TestLogFile = "ErrorLog_Test.log";
public static IEnumerable ReadLines(string path)
{
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 0x1000, FileOptions.SequentialScan))
using (var sr = new StreamReader(fs, Encoding.UTF8))
{
string line;
while ((line = sr.ReadLine()) != null)
{
yield return line;
}
}
}
[TestCleanup]
public async Task CleanUp()
{
//File.Delete(TestLogFile);
SemaphoreSlim gate = new SemaphoreSlim(1);
await gate.WaitAsync();
try
{
File.Delete(TestLogFile);
}
finally
{
gate.Release();
}
}
[TestMethod]
public void LogException_AppendsToExistingFile_WhenFileExists()
{
// Arrange
File.WriteAllText(TestLogFile, "Existing log entry\n");
var exception = new Exception("Test error", new Exception("Inner error"));
var severity = Logger.Severity.CRITICAL;
string expectedFileLog = $"{exception.Message} - {exception.InnerException.Message}";
string expectedConsoleLogPart = $"{exception.Message} - {exception.InnerException.Message}";
// Act
Logger.LogException(exception, severity, TestLogFile);
// Assert
string fileContent = string.Join("\n", ReadLines(TestLogFile));
Console.WriteLine(fileContent);
StringAssert.Contains(fileContent, "Existing log entry\n", "Original log entry should remain.");
StringAssert.Contains(fileContent, expectedFileLog, "New log entry should be appended.");
}
[TestMethod]
public void LogException_CreatesFileAndLogsMessage_WhenFileDoesNotExist()
{
var exception = new Exception("Test error", new Exception("Inner error"));
var severity = Logger.Severity.ERROR;
string expectedFileLog = $"{exception.Message} - {exception.InnerException.Message}";
string expectedConsoleLogPart = $"{exception.Message} - {exception.InnerException.Message}";
// Act
Logger.LogException(exception, severity, TestLogFile);
// Assert
Assert.IsTrue(File.Exists(TestLogFile), "Log file should be created.");
string fileContent = string.Join("\n", ReadLines(TestLogFile));
Console.WriteLine(fileContent);
StringAssert.Contains(fileContent, expectedFileLog, "Log file should contain the logged message.");
}
[TestMethod]
public void LogException_HandlesNullInnerException()
{
var exception = new Exception("Test error");
var severity = Logger.Severity.INFORMATION;
string expectedFileLog = $"{exception.Message} - ";
string expectedConsoleLogPart = $"{exception.Message} - ";
// Act
Logger.LogException(exception, severity, TestLogFile);
// Assert
string fileContent = string.Join("\n", ReadLines(TestLogFile));
Console.WriteLine(fileContent);
StringAssert.Contains(fileContent, expectedFileLog, "Log file should handle null inner exception.");
}
}
< /code>
Я пытался просто запустить файл. Delete () < /code>, а также логику, в настоящее время показанная в методе очистки < /code>. < /p>
Я также пытался реализовать решения в этих вопросах, однако я сталкиваюсь с теми же проблемами, которые все: < /p>
worptions для файла Asynchrony. Запись в файл журнала, но сначала подождите, пока предыдущий ввод ввод -вывода /вывода закончится.
Добавление для подачи в асинхронное метод, называемый Timer. пакет, который решит эту проблему для меня, которую я не нашел?
Подробнее здесь: https://stackoverflow.com/questions/796 ... in-c-sharp