القوة متعددة الخيوط VB.NET فئة لعرض النتائج على نموذج واحد

StackOverflow https://stackoverflow.com/questions/273639

سؤال

لدي ويندوز شكل تطبيق يستخدم فئة المشتركة على جميع الكائنات المشتركة للتطبيق.الإعدادات فئة لديها مجموعة من الكائنات التي تفعل أشياء بشكل دوري ، ومن ثم هناك شيء من الاهتمام ، فإنها تحتاج إلى تنبيه النموذج الرئيسي ويكون ذلك التحديث.

أنا حاليا القيام بذلك من خلال الأحداث على الكائنات ، عند كل كائن تم إنشاؤه ، إضافة EventHandler إلى خرائط الحدث مرة أخرى إلى النموذج.ومع ذلك أنا الوقوع في بعض المشاكل التي تشير إلى أن هذه الطلبات ليست دائما تنتهي على النسخة الرئيسية من شكل.على سبيل المثال ، طلب إعلام صينية الرمز ، ولكن عندما شكل يلتقط الحدث ومحاولات عرض فقاعة, ما من فقاعة تظهر.ومع ذلك ، إذا قمت بتغيير هذا الكود لجعل رمز مرئية (على الرغم من أنه هو بالفعل) ، ومن ثم عرض فقاعة, الثانية يظهر رمز ويعرض فقاعة بشكل صحيح.

وقد أي شخص تعمل في هذا من قبل ؟ هل هناك طريقة أستطيع أن قوة من الأحداث ليتم القبض عليه من قبل مثيل واحد من شكل ، أو هل هناك طريقة مختلفة تماما في التعامل مع هذا ؟ أنا يمكن أن الرمز البريدي عينات إذا لزم الأمر, لكن أعتقد انها مشتركة خيوط المشكلة.

مزيد من المعلومات: أنا حاليا باستخدام بي.InvokeRequired في معالج الحدث على انه دائما بإرجاع خطأ في هذه الحالة.أيضا, الثاني رمز علبة إنشاؤها عندما جعله مرئيا من هذا النوع لا يملك قائمة السياق على ذلك ، في حين أن "ريال مدريد" رمز لا - لا دليل على أن أي شخص ؟

انا ذاهب الى سحب شعري!هذا لا يمكن أن يكون من الصعب!

الحل:بفضل nobugz على فكرة, و هذا يؤدي بي إلى مدونة أنا الآن باستخدام (الذي يعمل بشكل جميل, على الرغم من أنني لا يمكن أن تساعد في التفكير هناك طريقة أفضل للقيام بذلك).أضفت خاصة متغير منطقية إلى شكل يسمى "IsPrimary" ، إضافة التعليمات البرمجية التالية إلى النموذج المنشئ:

    Public Sub New()
        If My.Application.OpenForms(0).Equals(Me) Then
            Me.IsFirstForm = True
        End If
    End Sub

مرة واحدة يتم تعيين متغير البناء والتشطيبات ، رؤساء الحق في معالج الحدث و أنا أتعامل مع الأمر بهذه الطريقة (التحذير:منذ شكل أبحث عنه هو الشكل الأساسي للتطبيق،.التطبيق.OpenForms(0) يحصل على ما أريد.إذا كنت تبحث عن المثيل الأول من عدم بدء تشغيل النموذج ، يجب تكرار خلال حتى وجدت):

    Public Sub EventHandler()
        If Not IsFirstForm Then
            Dim f As Form1 = My.Application.OpenForms(0)
            f.EventHandler()
            Me.Close()
        ElseIf InvokeRequired Then
            Me.Invoke(New HandlerDelegate(AddressOf EventHandler))
        Else
            ' Do your event handling code '
        End If
    End Sub

فهو أولا التحقق لمعرفة ما إذا كان قيد التشغيل على الشكل الصحيح - إن لم يكن, ثم استدعاء النموذج الصحيح.بعد ذلك يتحقق إذا كان الموضوع هو الصحيح ، ويدعو UI إذا لم يكن.ثم يدير رمز الحدث.أنا لا أحب أن الأمر يحتمل ثلاثة المكالمات, ولكن لا أستطيع التفكير في طريقة أخرى للقيام بذلك.يبدو أن تعمل بشكل جيد ، على الرغم من انها قليلا مرهقة.إذا كان أي شخص لديه طريقة أفضل للقيام بذلك ، أحب أن أسمع ذلك!

مرة أخرى شكرا على كل مساعدة - هذا كان على وشك أن تدفع لي مجنون!

هل كانت مفيدة؟

المحلول

وأعتقد أنه هو خيوط المشكلة أيضا.هل تستخدم التحكم.الاحتجاج() في معالج الحدث?.صافي عادة يمسك الانتهاكات عند تصحيح التطبيق ولكن هناك حالات لا يمكن.NotifyIcon هو واحد منهم ، لا يوجد مقبض الإطار للتحقق من موضوع التقارب.

تحرير بعد العملية غيرت السؤال:

الكلاسيكية VB.NET الفخ هو المرجعية شكل مثيل لها اسم النوع.مثل Form1.NotifyIcon1.شيء.لا يعمل كما هو متوقع عند استخدام خيوط.فإنه سيتم إنشاء جديد سبيل المثال من فئة Form1, عدم استخدام القائمة سبيل المثال.هذه الحالة ليست مرئية (Show() لم يطلق عليه) و هو خلاف ذلك ميتة تماما لأنه يعمل على ترابط هذا لا مضخة رسالة حلقة.رؤية ثانية أيقونة تظهر الميت لإعطاء بعيدا.لذلك هو الحصول على InvokeRequired = False عندما تعرف أنك تستخدم من الموضوع.

يجب استخدام إشارة إلى شكله الحالي سبيل المثال.إذا كان من الصعب أن يأتي من قبل (عادة ما تمر "لي" كحجة منشئ الفئة), يمكنك استخدام التطبيق.OpenForms:

  Dim main As Form1 = CType(Application.OpenForms(0), Form1)
  if (main.InvokeRequired)
    ' etc...

نصائح أخرى

استخدام التحكم.InvokeRequired لتحديد ما إذا كنت على الطريق الصحيح الخيط ، ثم استخدام جهاز التحكم.الاحتجاج إذا كنت لا.

يجب أن ننظر في وثائق Invoke على شكل.وسوف تسمح لك لجعل رمز التحديثات شكل تعمل على الخيط الذي يملك شكل (التي يجب عليها أن تفعل, Windows النماذج ليست موضوع آمنة).شيء مثل خاصة مندوب الفرعية UpdateStatusDelegate(ByVal نيوستاتوس as String)

Public sub UpdateStatus(ByVal نيوستاتوس as String) إذا كان لي.InvokeRequired ثم Dim d As New UpdateStatusDelegate(AddressOf UpdateStatus) لي.الاحتجاج(د,new Object() {نيوستاتوس}) آخر 'تحديث شكل حالة End If

إذا قمت بتوفير بعض التعليمات البرمجية سأكون سعيدا لتقديم مصممة أكثر على سبيل المثال.

تحرير بعد العملية قال أنهم يستخدمون InvokeRequired.

قبل استدعاء InvokeRequired ، تحقق من أن شكل التعامل مع أنشئت هناك HandleCreated المنشأة انا اجد.InvokeRequired دائما بإرجاع خطأ إذا كان عنصر التحكم لا تملك حاليا التعامل معها ، هذا يعني ثم رمز غير الآمن موضوع حتى ولو كنت قد فعلت الشيء الصحيح لجعل ذلك.تحديث سؤالك عندما تكتشف.بعض التعليمات البرمجية سوف تكون مفيدة جدا.

في c# يبدو مثل هذا:

private EventHandler StatusHandler = new EventHandler(eventHandlerCode)
void eventHandlerCode(object sender, EventArgs e)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(StatusHandler, sender, e);
        }
        else
        {
          //do work
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top