سؤال

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

شكرا في وقت مبكر.

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        count = 0;
        for (int j = 1; j < 255; j++)
            for (int i = 1; i < 255; i++)
            {
                Ping ping = new Ping();
                PingReply pingreply = ping.Send(IPAddress.Parse(locip[0] + "." + locip[1] + "." + j + "." + i));

                if (pingreply.Status == IPStatus.Success)
                {
                    status = "o";
                    repAddress = pingreply.Address.ToString(); ;
                    repRoundtrip = pingreply.RoundtripTime.ToString();
                    repTTL = pingreply.Options.Ttl.ToString();
                    repBuffer = pingreply.Buffer.Length.ToString();

                    string[] lineBuffer = { status, repAddress, repRoundtrip, repTTL, repBuffer };
                    ipList.Rows.Add(lineBuffer);
                    count += 1;
                    progressBar.Value += 1;
                }

            }


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

المحلول

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

progressBar.Invoke(new MethodInvoker(UpdateProgressBarbyOne));
...

private void UpdateProgressBarByOne() {
  progressBar.Value += 1;  
}

نصائح أخرى

لا يمكنك الوصول مباشرة إلى برنامج ProgressBar1 (أو أي عنصر واجهة مستخدم أخرى) من حدث "Dowork" الخلفي ، يجب عليك استخدام BackgroundWorker1.ProgressChanged Method والتعامل مع الحدث ProgressChanged:

// instead of progressBar.Value += 1
// use the following

const int total = 254 * 254;
backgroundWorker1.ReportProgress(count / total);

يجب تعيين WorkerReportSprogress إلى True وحدث التقدم في الطريقة التالية

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // assuming the Minimum = 0 and Maximum = 100 on progressBar
    progressBar.Value = e.ProgressPercentage;
}

آه أنا أحب الخيوط. يجعل البرامج أكثر إثارة للاهتمام ...

لذا عندما بدأت في التعرف على كيفية تقديم تطبيقات مستجيبة ، صادفت الوظيفة: application.doevents ()

(http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx)

ما يفعله هذا هو أن النموذج الخاص بك لمعالجة بعض أحداث النافذة التي يتلقاها. أعتقد أن الكود الخاص بك قد يتغير ليشمل مكالمة بعد كل طلب بينغ ...

IE ضمن معالج الأحداث على النقر فوق

count = 0;
        for (int j = 1; j < 255; j++)
            for (int i = 1; i < 255; i++)
            {
                Ping ping = new Ping();
                PingReply pingreply = ping.Send(IPAddress.Parse(locip[0] + "." + locip[1] + "." + j + "." + i));

                if (pingreply.Status == IPStatus.Success)
                {
                    status = "o";
                    repAddress = pingreply.Address.ToString(); ;
                    repRoundtrip = pingreply.RoundtripTime.ToString();
                    repTTL = pingreply.Options.Ttl.ToString();
                    repBuffer = pingreply.Buffer.Length.ToString();

                    string[] lineBuffer = { status, repAddress, repRoundtrip, repTTL, repBuffer };
                    ipList.Rows.Add(lineBuffer);
                    count += 1;
                    progressBar.Value += 1;
                }
                Application.DoEvents(); //but not too often.
            }

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

قد لا أستخدم هذه الطريقة اعتمادًا على التطبيق. بدلاً من ذلك ، ما سأفعله بالفعل هو إنشاء العديد من "القطارات" المعالجة ؛ واحد لكل نواة وحدة المعالجة المركزية التي كان النظام. سأضيف IPS ليتم مسح ضوئي إلى كائن قائمة انتظار ، ثم سأبدأ من 2 إلى 4 مثيلات من المواضيع (http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx) كل منها أخذ عنصر من قائمة الانتظار بدوره ، معالجة المعلومات (أي القيام بمنطق ping) ووضع النتيجة في قائمة انتظار أخرى ؛ وابنة قائمة الانتظار. في كل مرة ينهي القطار عنصرًا للعمل ، فإنه يرفع حدثًا في الطرف الآخر الذي سيكون هناك معالج في النموذج. استخدام الاستدعاء لجعل مؤشرات الترابط مكالمات آمنة (http://msdn.microsoft.com/en-us/library/ms171728.aspx) في النموذج الخاص بي ، سأقوم بتحديث معلومات واجهة المستخدم وفقًا لذلك.

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

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