C# 使用ETW和语义日志应用程序块的文件锁

C# 使用ETW和语义日志应用程序块的文件锁,c#,.net,logging,enterprise-library,etw,C#,.net,Logging,Enterprise Library,Etw,我们创建了ETW EventSource的一个非常简单的实现,该实现由语义日志应用程序块(通过RollingFlatFileLogs)使用 基本设置如下所示: [EventSource(Name = "My Applicaiton")] public partial class MyEventSource : EventSource { /// <summary> /// The log /// </summary> public stat

我们创建了ETW EventSource的一个非常简单的实现,该实现由语义日志应用程序块(通过RollingFlatFileLogs)使用

基本设置如下所示:

[EventSource(Name = "My Applicaiton")]
public partial class MyEventSource : EventSource
{
    /// <summary>
    /// The log
    /// </summary>
    public static MyEventSource Log = new MyEventSource();
然而,我们已经看到的问题是,一些开发人员看到锁定了停止执行的日志文件。此时会显示“文件正在使用,无法写入”的消息

为什么会这样?为什么即使日志记录是异步运行的,它也会结束进程

我们如何防止这种情况在未来发生?有没有一种方法可以强化我们的日志实现,以便在出现类似这样的错误时可以滚动文件

谢谢

编辑:我已捕获问题的堆栈跟踪:

 The process cannot access the file 'C:\ServiceRegistry\services.log' because it is               being used by another process.

    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
     at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
    at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
    at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
    at System.IO.FileInfo.Open(FileMode mode, FileAccess access, FileShare share)
    at Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Sinks.RollingFlatFileSink..ctor(String fileName, Int32 rollSizeKB, String timestampPattern, RollFileExistsBehavior rollFileExistsBehavior, RollInterval rollInterval, Int32 maxArchivedFiles, Boolean isAsync)
    at Microsoft.Practices.EnterpriseLibrary.SemanticLogging.RollingFlatFileLog.CreateListener(String fileName, Int32 rollSizeKB, String timestampPattern, RollFileExistsBehavior rollFileExistsBehavior, RollInterval rollInterval, IEventTextFormatter formatter, Int32 maxArchivedFiles, Boolean isAsync)

在使用IISExpress进行本地开发时,我也看到了同样的问题,我得到了“进程无法访问文件'C:\MyPath\OurProductName.2016-01-05.log',因为它正被另一个进程使用。”错误消息。如果我在Global.asax文件的Application_Start中放置一个断点,我注意到它会在Application_Start中运行两次。第二次是导致锁问题的原因。我发现阻止这种情况的唯一方法是查找我自己唯一的文件名(见下面的代码),或者在IISExpress中编码时关闭日志记录

以下是检查唯一文件名的例行程序(每次在IISExpress中重新编译或运行应用程序时,您将获得多个文件):


Chris,这将有助于获取堆栈跟踪来诊断此问题。我一直都看到这一点,对我们来说,不同的应用程序使用同一个文件。@Chris你能在上记录问题以便跟踪和讨论吗?如果您可以包含有关应用程序的信息(应用程序的多个实例是否同时运行)以及应用程序关闭时侦听器的处理方式,那就太好了。谢谢
var listener = Microsoft.Practices.EnterpriseLibrary.SemanticLogging.RollingFlatFileLog.CreateListener("C:\\ServiceRegistry\\services.log", 5120, null, Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Sinks.RollFileExistsBehavior.Increment, Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Sinks.RollInterval.None, null, 10, true);

        listener.EnableEvents(MyEventSource.Log, System.Diagnostics.Tracing.EventLevel.LogAlways);


        // Log some things
        MyEventSource.Log.ApplicationStarting();
 The process cannot access the file 'C:\ServiceRegistry\services.log' because it is               being used by another process.

    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
     at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
    at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
    at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
    at System.IO.FileInfo.Open(FileMode mode, FileAccess access, FileShare share)
    at Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Sinks.RollingFlatFileSink..ctor(String fileName, Int32 rollSizeKB, String timestampPattern, RollFileExistsBehavior rollFileExistsBehavior, RollInterval rollInterval, Int32 maxArchivedFiles, Boolean isAsync)
    at Microsoft.Practices.EnterpriseLibrary.SemanticLogging.RollingFlatFileLog.CreateListener(String fileName, Int32 rollSizeKB, String timestampPattern, RollFileExistsBehavior rollFileExistsBehavior, RollInterval rollInterval, IEventTextFormatter formatter, Int32 maxArchivedFiles, Boolean isAsync)
private static string GetUniqueFileName(string directoryName)
{
   string baseFileName = string.Format("OurProductName.{0}",
      DateTime.Now.ToString("yyyy-MM-dd"));
   string currentFileName = Path.Combine(directoryName, 
      string.Format("{0}.log", baseFileName));
   int number = 1;
   while (System.IO.File.Exists(currentFileName))
   {
      currentFileName = Path.Combine(directoryName, 
         string.Format("{0}.{1}.log", baseFileName, number++));
    }

    return currentFileName;
}