C#FileSystemWatcher在应用程序退出(Win10)时冻结/死锁

时间:2018-07-13 01:32:46

标签: c# .net-4.0 windows-10 filesystemwatcher

今天我遇到了一个很奇怪的问题……FileSystemWatcher在应用程序退出时导致了“死锁”,但仅在Win10系统上。在Win7和8上,一切都很好。

我也暂时解决了这个问题,但是,我想知道是否有人遇到过类似的问题。

这是应该在Win10上创建行为的代码

public class FSW_Test
{
    private FileSystemWatcher _fsw;

    public FSW_Test()
    {

    }

    public void Start(string path)
    {
        if (Directory.Exists(path))
        {
            _fsw?.Dispose();
            _fsw = new FileSystemWatcher()
            {
                Path = path,
                EnableRaisingEvents = true,
                IncludeSubdirectories = false,
                InternalBufferSize = (8 * 1024),
                NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.FileName | NotifyFilters.DirectoryName,
                Filter = "*.*"
            };
            _fsw.Changed += OnChanged;
            _fsw.Created += OnCreated;
            _fsw.Renamed += OnRenamed;
            _fsw.Deleted += OnDeleted;
        }
    }

    public void Stop()
    {
        _fsw?.Dispose();
    }

    private void OnChanged(object source, FileSystemEventArgs e)
    {
        // do something
    }

    private void OnCreated(object source, FileSystemEventArgs e)
    {
        // do something
    }

    private void OnRenamed(object source, RenamedEventArgs e)
    {
        // do something
    }

    private void OnDeleted(object source, FileSystemEventArgs e)
    {
        // do something
    }
}

如果您现在实例化该类,请调用Start("some dir"),在该目录中创建一个文件,调用Stop()并尝试关闭您的应用程序,此时您应该会卡住。 (至少是我)

现在是临时解决方案...

如您所见,我在这里使用NotifyFilters.CreationTimeNotifyFilters.LastAccessNotifyFilters.LastWrite。如果我删除了这些NotifyFilters,应用程序将关闭并且没有“死锁” FileSystemWatcher

我在Win10下错过了什么吗?还是真的像this article所描述的那样,但仅在Win10下?

编辑(14.07.2018): 似乎有用,不要使用那些NotifyFilters仅在经过4/10测试的系统上有效。

WinDbg告诉我以下内容:

ClrThread  DbgThread  OsThread    LockType    Lock              LockLevel
------------------------------------------------------------------------------
0x9        22         0xf98       SyncBlock   0000000022210368     

--

0:016> !mdt 00000000034dcd28
00000000034dcd28 (System.IO.FileSystemWatcher)
    __identity:NULL (System.Object)
    site:NULL (System.ComponentModel.ISite)
    events:NULL (System.ComponentModel.EventHandlerList)
    directory:0000000002b8d9a8 (System.String) Length=22, String="C:\Users\Admin\Desktop"
    filter:00000000034dcdc8 (System.String) Length=3, String="*.*"
    directoryHandle:NULL (Microsoft.Win32.SafeHandles.SafeFileHandle)
    notifyFilters:0x7b(FileName|DirectoryName|Size)     (System.IO.NotifyFilters)
    includeSubdirectories:false (System.Boolean)
    enabled:false (System.Boolean)
    initializing:false (System.Boolean)
    internalBufferSize:0x2000 (System.Int32)
    changedResult:(System.IO.WaitForChangedResult) VALTYPE (MT=00007ffbb6df1cb8, ADDR=00000000034dcda8)
    isChanged:false (System.Boolean)
    synchronizingObject:NULL (System.ComponentModel.ISynchronizeInvoke)
    readGranted:false (System.Boolean)
    disposed:true (System.Boolean)
    currentSession:0x4 (System.Int32)
    onChangedHandler:NULL (System.IO.FileSystemEventHandler)
    onCreatedHandler:NULL (System.IO.FileSystemEventHandler)
    onDeletedHandler:NULL (System.IO.FileSystemEventHandler)
    onRenamedHandler:NULL (System.IO.RenamedEventHandler)
    onErrorHandler:NULL (System.IO.ErrorEventHandler)
    stopListening:true (System.Boolean)
    runOnce:false (System.Boolean)

提前获得大THX!

此致

塞巴斯蒂安

0 个答案:

没有答案