Вопрос

Я новичок в программировании и не могу найти или узнать, что искать для отладки потока, запущенного методом SendAsync. Код хорошо работает с использованием метода Send, но при использовании SendAsync он переходит к waiter.WaitOne (), но я никогда не получаю обратный вызов (я думаю, так он и называется) к myPing_PingCompleted. Итак, два вопроса, как мне отладить код, когда он запускает новый поток. Я использую 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;
        }
Это было полезно?

Решение

Я предполагаю, что вы помещаете точку останова в метод myPing_PingCompleted, но в режиме отладки его просто нет. Это правильно?

Код выдает какую-то ошибку? Если вы перебираете код, вызывает ли он myPing.SendAsync с правильными параметрами?

Я только что попробовал ваш код (без IPQueue, потому что это похоже на ваш пользовательский класс). Это прекрасно работает на моем конце. Я использовал один действительный IP-адрес и какой IP-адрес не существует. Это сработало хорошо в обоих случаях.

Изменить для новой информации

Хорошо, я только что попробовал это в приложении формы Windows, и это НЕ РАБОТАЕТ. Когда я попробовал это прежде, чем это было в модульном тесте. По сути, может показаться, что поток, используемый для визуализации оконной формы и обработки событий, не может быть использован для создания асинхронных запросов (возможно, потому что это поток переднего плана). Но вы можете легко обойти его, создав еще один поток для выполнения пинга.

На самом деле, в идеале, именно так вы и должны это делать. Чтобы приложение формы Windows не блокировалось, когда поток занят, хорошим принципом является выполнение всей фоновой работы в отдельном потоке. Это будет держать форму окна отзывчивым. Однако будьте осторожны, при попытке доступа к элементам управления с использованием потоков фонового режима будет выдано исключение. Лучше всего прочитать все значения, которые вы хотите, в частные переменные, а затем запустить поток, который выполнит всю работу, попросит этот поток обновить другой набор переменных, а затем попросит поток forground прочитать переменные и обновить элементы управления.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top