1

ローカルサブネット上のすべての可能なIPにpingを実行し、DataGridViewでそのようなIPのリストを提供するための単純なネットワークツールを作成しようとしています。私は、新進のプログラマーとして出くわすのに良いことであるスレッド化を検討しなければならないのは初めてです。申し訳ありませんが、おそらく私に説明する必要がありますが、私の心の中ではこれはうまくいくはずです。それをbackgroundworkerスレッドに入れようとする前に、アプリケーションがハングして「応答しません」と表示されました。

よろしくお願いします。

        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;
                }

            }


    }
4

3 に答える 3

2

backgroundWorker1の「DoWork」イベントからprogressBar1(またはその他のUI要素)に直接アクセスすることはできません。backgroundWorker1.ProgressChangedメソッドを使用してProgressChangedイベントを処理する必要があります。

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

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

WorkerReportsProgressをtrueに割り当て、ProgressChangedのイベントを次のメソッドに割り当てる必要があります

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // assuming the Minimum = 0 and Maximum = 100 on progressBar
    progressBar.Value = e.ProgressPercentage;
}
于 2010-01-20T23:58:23.243 に答える
1

問題の一部は、バックグラウンドスレッドからUI要素に直接アクセスしていることです。このフィールドprogressBarはおそらくUIプログレスバーコントロールであり、UIスレッドからのみ安全にアクセスできます。UIスレッドからこの値を設定するには、.Invokeの呼び出しを使用する必要があります。

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

private void UpdateProgressBarByOne() {
  progressBar.Value += 1;  
}
于 2010-01-20T23:35:55.103 に答える
0

ああ、私はスレッディングが大好きです。それはプログラムをとても面白くします...

レスポンシブアプリケーションの作成方法を学び始めたとき、次の関数に出くわしました:Application.DoEvents()

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

これにより、フォームは受信したウィンドウイベントの一部を処理します。各pingリクエストの後に呼び出しを含めるようにコードを変更できると思います...

つまり、onclickイベントハンドラー内

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.
            }

さて、これはドットネット以前の時代に戻って、今まで生き残っていますが、それはあなたが軽く取る必要があるものではありません。フォームの別のボタンをクリックすると、実行を試みる別のスレッドが開始されます。注意しないと、フォームでスレッド例外が発生します。一部の開発者はこれを使用しないと言うでしょうが、あなたが始めてから私はそれを試してみると思います:)

アプリケーションによっては、この方法を使用しない場合があります。代わりに、私が実際に行うことは、いくつかの処理「トレイン」を作成することです。システムが持っていたCPUコアごとに1つ。スキャンするipsをキューオブジェクトに追加してから、スレッドの2〜4個のインスタンスを起動します(http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx)それぞれが順番にアイテムをキューから取り出し、情報を処理し(つまり、pingロジックを実行し)、結果を別のキューに入れます。および出力キュー。列車が仕事のためにアイテムを完成させるたびに、それはもう一方の端でイベントを発生させ、その反対側にハンドラーがフォームにあります。Invokeを使用してスレッドセーフな呼び出しを行う(http://msdn.microsoft.com/en-us/library/ms171728.aspx)フォームでは、それに応じてUIの情報を更新します。

スレッディングは楽しいです:)時間の経過とともに、MSMQを使用して、他のコンピューターのマルチコアを使用して画像処理(またはpa .......;)などのジョブを実行するシステムを作成できることがわかります。

于 2010-01-21T00:34:55.340 に答える