0

私はプログラミングが初めてで、SendAsync メソッドで開始されたスレッドをデバッグするために何を検索すればよいかわかりません。コードは Send メソッドを使用してうまく動作しますが、SendAsync を使用すると waiter.WaitOne() に移動しますが、myPing_PingCompleted へのコールバック (それが呼び出されたものだと思います) を受け取ることはありません。したがって、新しいスレッドを開始するときにコードをデバッグするにはどうすればよいかという 2 つの質問があります。C# Express を使用しているため、VS としてすべてのデバッグ ツールが含まれていない可能性があります。そして、自分のコードでどこが間違っているのか考えてください。ありがとう

using System;
using System.CodeDom;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Threading;
using System.Net;

private void btnPingAsync_Click(object sender, EventArgs e)
    {
        string bIP = txtStartIP.Text;
        string eIP = txtEndIP.Text;
        int timeOut;
        int cnt = 0;
        if (eIP == null) eIP = bIP;
        Ping myPing = new Ping();
        PingOptions parmPing = new PingOptions();
        AutoResetEvent waiter = new AutoResetEvent(false);
        myPing.PingCompleted +=new PingCompletedEventHandler(myPing_PingCompleted);
        string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        byte[] dataBuffer = Encoding.ASCII.GetBytes(data);
        if (!int.TryParse(txtTimeOut.Text, out timeOut)) timeOut = 120;
        parmPing.DontFragment = true;
        parmPing.Ttl = 32;
        pbQueueStatus.Minimum = 0;
        pbQueueStatus.Step = 10;
        pbQueueStatus.Value = 0;
        pbQueueStatus.Style = ProgressBarStyle.Continuous;




        if (verify.ValidIPAddress(bIP) && verify.ValidIPAddress(eIP))
        {
            IPQueue = build.IPAddressQueue(bIP, eIP);
            pbQueueStatus.Maximum = IPQueue.Count;
            pbQueueStatus.TopLevelControl.UseWaitCursor= true;
            pbQueueStatus.Visible = true;
            while (IPQueue.Count > 0)
            {
                myPing.SendAsync(IPQueue.Dequeue(), timeOut, dataBuffer, parmPing, waiter);
                waiter.WaitOne();
                if (++cnt > 10)
                {
                    pbQueueStatus.PerformStep();
                    cnt = 0;
                }
            }
        }
    }

    private void myPing_PingCompleted(Object sender, PingCompletedEventArgs e)
    {

        PingReply reply = e.Reply;
        ((AutoResetEvent)e.UserState).Set();
        if (reply .Status == IPStatus .Success )
        {
            dosomething;
        }
4

1 に答える 1

0

myPing_PingCompleted メソッドに breakpoinit を入れていると仮定していますが、デバッグモードではそこには行きません。そうですか?

コードは何らかのエラーをスローしていますか? コードをステップ実行すると、正しいパラメーターで myPing.SendAsync が呼び出されますか?

私はちょうどあなたのコードを試しました (それはあなたのカスタム クラスのように見えるので、IPQueue なしで)。私の側ではうまくいきます。1 つの有効な IP と、存在しない IP を使用しました。どちらの場合もうまくいきました。

新しい情報を編集する

わかりました、Windowsフォームアプリケーションで試してみましたが、うまくいきません。単体テストの前に試したとき。基本的に、Windows フォームのレンダリングとイベントの処理に使用されるスレッドは、非同期要求の作成に使用できないようです (フォアグラウンド スレッドである可能性があります)。ただし、ping を実行する別のスレッドを作成することで、かなり簡単に回避できます。

実際、理想的には、とにかくそれを行う必要があります。スレッドがビジー状態のときに Windows フォーム アプリがロックしないようにするには、別のスレッドですべてのバックラウンド作業を行うことをお勧めします。これにより、Windows フォームの応答性が維持されます。ただし、バックラウンド スレッドを使用してコントロールにアクセスしようとすると、例外がスローされることに注意してください。必要なすべての値をプライベート変数に読み取り、すべての作業を実行するスレッドを起動し、そのスレッドに別の変数セットを更新させてから、フォアグラウンド スレッドに変数を読み取らせ、コントロールを更新させるのが最善の方法です。

于 2009-09-16T20:37:42.960 に答える