Мы только начали сталкиваться с странной проблемой с FileSystemWatcher, где вызов Dispose (), кажется, зависает. Это код, который какое-то время работал без проблем, но мы только что обновились до .NET3.5 SP1, поэтому я пытаюсь выяснить, видел ли кто-нибудь такое поведение. Вот код, который создает FileSystemWatcher:
if (this.fileWatcher == null)
{
this.fileWatcher = new FileSystemWatcher();
}
this.fileWatcher.BeginInit();
this.fileWatcher.IncludeSubdirectories = true;
this.fileWatcher.Path = project.Directory;
this.fileWatcher.EnableRaisingEvents = true;
this.fileWatcher.NotifyFilter = NotifyFilters.Attributes;
this.fileWatcher.Changed += delegate(object s, FileSystemEventArgs args)
{
FileWatcherFileChanged(args);
};
this.fileWatcher.EndInit();
Это используется для обновления изображения состояния объекта TreeNode (немного скорректировано для удаления бизнес-информации):
private void FileWatcherFileChanged(FileSystemEventArgs args)
{
if (this.TreeView != null)
{
if (this.TreeView.InvokeRequired)
{
FileWatcherFileChangedCallback d = new FileWatcherFileChangedCallback(FileWatcherFileChanged);
this.TreeView.Invoke(d, new object[]
{
args
});
}
else
{
switch (args.ChangeType)
{
case WatcherChangeTypes.Changed:
if (String.CompareOrdinal(this.project.FullName, args.FullPath) == 0)
{
this.StateImageKey = GetStateImageKey();
}
else
{
projectItemTreeNode.StateImageKey = GetStateImageKey();
}
break;
}
}
}
}
Что-то нам не хватает или это аномалия из .NET3.5 SP1?





Просто мысль ... Есть ли шанс, что здесь проблема с тупиком?
Вы вызываете TreeView.Invoke, что является блокирующим вызовом. Если изменение файловой системы происходит так же, как вы нажимаете любую кнопку, вызывающую вызов FileSystemWatcher.Dispose (), ваш метод FileWatcherFileChanged будет вызван в фоновом потоке и вызовет TreeView.Invoke, который будет блокироваться до тех пор, пока ваш поток формы не сможет обработать запрос Invoke. . Однако поток вашей формы будет вызывать FileSystemWatcher.Dispose (), который, вероятно, не вернется, пока не будут обработаны все ожидающие запросы на изменение.
Попробуйте изменить .Invoke на .BeginInvoke и посмотрите, поможет ли это. Это может указать вам правильное направление.
Конечно, это также может быть проблема .NET 3.5SP1. Я просто размышляю здесь на основе предоставленного вами кода.
У нас тоже есть эта проблема. Наше приложение работает на .Net 2.0, но скомпилировано VS 2008 SP1. У меня также установлен .NET 3.5 SP1. Я понятия не имею, почему это происходит, это не похоже на проблему с тупиком с нашей стороны, поскольку в этот момент другие потоки не работают (это во время завершения работы приложения).
Скотт, мы иногда наблюдали проблемы с control.Invoke в .NET 2. Попробуйте переключиться на control.BeginInvoke и посмотрите, поможет ли это.
Это позволит потоку FileSystemWatcher немедленно вернуться. Я подозреваю, что ваша проблема заключается в том, что control.Invoke блокируется, что приводит к зависанию FileSystemWatcher при удалении.
Кажется, это так и является правильным решением. Я вручил ответ Джонатану, поскольку он ответил первым.
Если вы используете FileSystemWatcher, вы потенциально используете другой поток; поток FileSystemWatcher может быть заблокирован при попытке вызова в потоке пользовательского интерфейса.