سؤال

وC # 2008

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

في التعليمات البرمجية أدناه أنا التحقق إذا كان CancellationPending إذا كان يطلق عليه CancelAsync في بلدي إلغاء زر انقر فوق الحدث، قبل القيام كل شيك. هل هذا صحيح؟ أيضا إذا فشل الاختيار I أيضا استدعاء CancelAsync وتعيين e.Cancel إلى true.

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

وشكرا جزيلا لأية نصيحة،

private void bgwProcessLogin_DoWork(object sender, DoWorkEventArgs e)
    {   
        /*
         * Perform at test to see if the background worker has been
         * cancelled by the user before attemping to continue to login.
         * 
         * Cancel background worker on any failed attemp to login
         */

        // Start with cancel being false as to reset this if cancel has been set to true
        // in the cancel button.
        e.Cancel = false;

        NetworkingTest connection_test = new NetworkingTest();
        if (!this.bgwProcessLogin.CancellationPending)
        { 
            // Check local LAN or Wireless connection               
            if (!connection_test.IsNetworkConnected())
            {
                // Update label
                if (this.lblRegistering.InvokeRequired)
                {
                    this.lblRegistering.Invoke(new UpdateRegisterLabelDelegate(UpdateRegisterLabel), "No network connection");
                }
                else
                {
                    this.lblRegistering.Text = "No network connection";
                }
                // Failed attemp
                this.bgwProcessLogin.CancelAsync();
                e.Cancel = true;
                return;
            }
            // Report current progress
            this.bgwProcessLogin.ReportProgress(0, "Network connected");
        }
        else
        {
            // User cancelled 
            e.Cancel = true;
            return;
        }

        // Test if access to Server is available
        if (!this.bgwProcessLogin.CancellationPending)
        {
            if (!connection_test.IsSIPServerAvailable())
            {
                // Update label
                if (this.lblRegistering.InvokeRequired)
                {
                    this.lblRegistering.Invoke(new UpdateRegisterLabelDelegate(UpdateRegisterLabel), "Server unavailable");
                }
                else
                {
                    this.lblRegistering.Text = "Server unavailable";
                }
                // Failed attemp
                this.bgwProcessLogin.CancelAsync();
                e.Cancel = true;
                return;
            }
            // Report current progress
            this.bgwProcessLogin.ReportProgress(1, "Server available");
        }
        else
        {
            // User cancelled 
            e.Cancel = true;
            return;
        }
        .
        .
        .
}


 private void bgwProcessLogin_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {   
        // Check for any errors
        if (e.Error == null)
        {
            if (e.Cancelled)
            {
                // User cancelled login or login failed                
            }
            else
            {
                // Login completed successfully                
            }
        }
        else
        {
            // Something failed display error
            this.statusDisplay1.CallStatus = e.Error.Message;
        }
    }


 private void bgwProcessLogin_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        this.lblRegistering.Text = e.UserState.ToString();
    }

private void btnCancel_Click(object sender, EventArgs e)
    {
        // Cancel the logging in process
        this.bgwProcessLogin.CancelAsync();
        this.lblRegistering.Text = "Logged out";
}
هل كانت مفيدة؟

المحلول

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

إذا يحتوي DoWork عمليات طويلة الأمد يمكنك استخدام شيء من هذا القبيل AbortableBackgroundWorker. شيء من هذا القبيل:

public class AbortableBackgroundWorker : BackgroundWorker
{
    private Thread workerThread;

    protected override void OnDoWork(DoWorkEventArgs e)
    {
        workerThread = Thread.CurrentThread;
        try
        {
            base.OnDoWork(e);
        }
        catch (ThreadAbortException)
        {
            e.Cancel = true; //We must set Cancel property to true!
            Thread.ResetAbort(); //Prevents ThreadAbortException propagation
        }
    }


    public void Abort()
    {
        if (workerThread != null)
        {
            workerThread.Abort();
            workerThread = null;
        }
    }
}

في هذه الحالة أنت حقا يمكن إجهاض العمليات المعلقة، ولكن لديك أيضا بعض القيود (لمزيد من المعلومات حول إجهاض موضوع المدارة وبعض القيود يرى <وأ href = "http://ondotnet.com/pub/a/dotnet/ 2003/02/18 / threadabort.html "يختلط =" noreferrer "> السباكة في أعماق ThreadAbortException عن طريق الدوار ).

وP.S. وأنا أتفق مع أوليفر أنه يجب التفاف InvokeRequired في شكل أكثر صالحة للاستعمال.

نصائح أخرى

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

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

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

وEvernything آخر تبدو جيدة جدا.

وهناك شيء واحد أنا لا تحتاج إلى استدعاء this.bgwProcessLogin.CancelAsync ()؛ كما يمكنك ان تحدد فقط هذا e.Cancel = صحيح؛

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