سؤال

لقد بدأنا للتو في مواجهة مشكلة غريبة مع 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.Invoc، وهي مكالمة حظر.إذا حدث تغيير في نظام الملفات بمجرد النقر فوق أي زر يؤدي إلى استدعاء FileSystemWatcher.Dispose()، فسيتم استدعاء أسلوب FileWatcherFileChanged الخاص بك على مؤشر ترابط الخلفية واستدعاء TreeView.Invoc، والذي سيتم حظره حتى يتمكن مؤشر ترابط النموذج الخاص بك من معالجة طلب الاستدعاء .ومع ذلك، سوف يقوم مؤشر ترابط النموذج الخاص بك باستدعاء FileSystemWatcher.Dispose()، والذي ربما لا يُرجع حتى تتم معالجة كافة طلبات التغيير المعلقة.

حاول تغيير .Invoce إلى .BeginInvoce ومعرفة ما إذا كان ذلك مفيدًا.قد يساعدك ذلك في توجيهك في الاتجاه الصحيح.

بالطبع، من الممكن أيضًا أن تكون مشكلة .NET 3.5SP1.أنا فقط أتكهن هنا بناءً على الكود الذي قدمته.

نصائح أخرى

سكوت، لقد رأينا أحيانًا مشكلات تتعلق بالتحكم.الاستدعاء في .NET 2.حاول التبديل إلى control.BeginInvoce ومعرفة ما إذا كان ذلك مفيدًا.

سيؤدي القيام بذلك إلى السماح لمؤشر ترابط FileSystemWatcher بالعودة على الفور.أظن أن مشكلتك تكمن بطريقة أو بأخرى في حظر عنصر التحكم.Invocation، مما يتسبب في تجميد FileSystemWatcher عند التخلص منه.

نحن أيضا نواجه هذه المشكلة.يعمل تطبيقنا على .Net 2.0 ولكن يتم تجميعه بواسطة VS 2008 SP1.لقد قمت بتثبيت .NET 3.5 SP1 أيضًا.ليس لدي أي فكرة عن سبب حدوث ذلك أيضًا، لا يبدو الأمر وكأنه مشكلة توقف تام من جانبنا حيث لا توجد سلاسل رسائل أخرى قيد التشغيل في هذه المرحلة (يكون ذلك أثناء إيقاف تشغيل التطبيق).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top