سؤال

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

مشكلتي هي أنه عند إحباط موضوع يلقي ThreadAbortException يمكن للمستخدم فقط النقر فوق متابعة.

كيف يمكنني التعامل مع هذا؟ كنت أحاول قمعها مثل ذلك ->

            try
        {
            Program.splashThread.Abort();
        }
        catch(Exception ex)
        {

        }

ولكن لدي شعور سوف يصرخ لي هنا ولا يعمل بأي طريقة.

شكرا!

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

المحلول

لا تحتاج إلى إلغاء الموضوع. سوف تثبت مع التعليمات البرمجية.

في نموذج شاشة البداية:

public void CloseSplash()
{
    Invoke((MethodInvoker)delegate
    {
        this.Close();
    });
}

في ملف البرامج.

private static Splash _splash = null;
public static void CloseSplash()
{
    if (_splash!= null)
    {
        _splash.CloseSplash();
    }
}

الآن، عندما تبدأ الطريقة الرئيسية الخاصة بك، إظهار البداية في موضوع:

Thread t = new Thread(new ThreadStart(delegate
{
    _splash = new Splash();
    _splash.ShowDialog();
}));

t.Start();

... وعندما تريد إغلاقها، فقط أغلقها:

Program.CloseSplash();

ثم لا داعي للقلق بشأن إحباط الموضوع؛ سوف يخرج بأمان.

نصائح أخرى

يرجى الرجوع إلى الرابط التالي الذي تم الحصول عليه القيام بحث Google (تم إرجاع النتيجة الأولى):

http://msdn.microsoft.com/en-us/library/5b50fdsz.aspx.

إيلاء اهتمام خاص لهذا الجزء:

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

باستخدام Throadabort لا يتم التوصية. إنه شر. لماذا لا تستخدم آلية أخرى مثل RESETEVENT (السيارات / اليدوية)؟ ابدأ تشغيل الخيط مع شاشة البداية، انتظر في الحدث. إذا تم إجراء رمز التحميل الآخر، قم بتعيين الحدث EN السماح لشاشة البداية بإغلاق نفسها بطريقة طبيعية (لطيفة).

بعض النقاط. استثناء Throadabort هو السبب في إجهاض الخيط. إنه ليس تأثير جانبي لك الاتصال بإحباطه. عند الاتصال بإحباطه على مؤشر ترابط، يجبر وقت التشغيل على استثناء Threadabort الذي سيتم نشره إلى الخيط. يمكن القبض على هذا الاستثناء لأنه يسمح للمستخدم بإجراء بعض التنظيف قبل إحباط الموضوع.

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

تصميم ذكي حقا في الواقع.

لذلك هو حقا موافق للقبض على هذا الاستثناء. في الواقع يجب عليك. ولكن اصطحب فقط هذا الاستثناء المحدد وليس الاستثناء العام. (كما هو مبين أدناه)

catch(ThreadAbortException ex)
{
   //This is an expected exception. The thread is being aborted
}

تغيير نوع الاستثناء إلى threadabortException. وإضافة دعوة إلى إعادة تعيين ()

    try
    {
        Program.splashThread.Abort();
    }
    catch(ThreadAbortException ex)
    {
        Thread.ResetAbort();
    }

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

لماذا تفعل ذلك؟ فقط قم بتعيين علامة استطلاعات الرأي، ثم في النهاية عندما يختار مؤشر الترابط، ستغلق نفسه.

جرب هذا الرمز. إنه يعمل بشكل جيد بالنسبة لي.

void splash()
{
    try {
        SplashScreen.SplashForm frm = new SplashScreen.SplashForm();
        frm.AppName = "HR";

        Application.Run(frm);
    }
    catch (ThreadAbortException ex)
    {
        Thread.ResetAbort();
    }
}

لقد استخدمت الحل الذي اقترحه فريدريك مورك. انها واضحة جدا وأنيقة. خلاف ذلك، وجدت مشكلة إذا قمت بإنشاء نموذج Splash قبل بدء التطبيق الحقيقي (Application.run (Mainform ...)):

إنه يثير InvalidoprationException الناجم عن مقبض النموذج لا يزال غير موجود في مؤشر ترابط الاتصال. لإنشاء المقبض مباشرة في مؤشر الترابط T (وتخطي هذا الاستثناء!) حاول تشغيل نموذج البداية بهذه الطريقة:

Thread t = new Thread(new ThreadStart(delegate
{
    _splash = new Splash();
     Application.Run(_splash);
}));

t.Start();

وإذا كنت تخطط لاستدعاء طريقة CloseSplash في المزيد من فروع البرنامج، فاجرض القيمة الخالية بعد المكالمة الأولى:

    private static Splash _splash = null;
    public static void CloseSplash()
    {
        if (_splash!= null)
        {
            _splash.CloseSplash();
            _splash=null;
        }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top