Как да използвам Ping.SendAsync, работещ с datagridview?

Имам приложение, което пингва всеки IP в datagridview, за да състави списък с реагиращи IP RoundtripTime. Когато завърша стъпката, ще върна RoundtripTime обратно към datagridview.

    ...
        foreach (DataGridViewRow row in this.gvServersList.Rows)
        {
            this.current_row = row;

            string ip = row.Cells["ipaddr_hide"].Value.ToString();

            ping = new Ping();

            ping.PingCompleted += new PingCompletedEventHandler(ping_PingCompleted);

            ping.SendAsync(ip, 1000);

            System.Threading.Thread.Sleep(5);
        }
    ...

    private static void ping_PingCompleted(object sender, PingCompletedEventArgs e)
    {
        var reply = e.Reply;
        DataGridViewRow row = this.current_row; //notice here
        DataGridViewCell speed_cell = row.Cells["speed"];
        speed_cell.Value = reply.RoundtripTime;
    }

Когато искам да използвам DataGridViewRow row = this.current_row;, за да получа текущия ред, но просто получавам грешка. Ключовата дума „това“ не е налична в статична функция. И така, как да върна стойността обратно към datagridview?

Благодаря ти.


person yiqun    schedule 17.03.2012    source източник


Отговори (2)


Какво каза KAJ. Но има шанс за смесване на резултатите от ping заявки, защото те не са свързани с ip адреси в мрежата. Човек не може да каже кой хост ще отговори пръв и ако има ping > 5ms всичко може да се случи, защото текущият ред се променя между обратните извиквания. Това, което трябва да направите, е да изпратите препратка към datagridviewrow на обратно извикване. За да направите това, използвайте претоварване на SendAsync:

ping.SendAsync(ip, 1000, row);

И в обратно извикване:

DataGridViewRow row = e.UserState as DataGridViewRow;

Може също да искате да проверите reply.Status, за да сте сигурни, че тази заявка не е изтекла.

person Nikola Markovinović    schedule 17.03.2012
comment
Благодаря, това е лесен начин за мен! - person yiqun; 17.03.2012

this се отнася за текущия екземпляр. Статичният метод не е срещу екземпляр, а вместо това само срещу типа. Така че няма наличен this.

Така че трябва да премахнете ключовата дума static от декларацията на манипулатора на събития. Тогава методът ще бъде срещу инстанцията.

Може също да се наложи да маршалирате кода обратно в нишката на потребителския интерфейс, преди да опитате да актуализирате изгледа на мрежата с данни - ако е така, тогава ще ви е необходим код като следното:

delegate void UpdateGridThreadHandler(Reply reply);

private void ping_PingCompleted(object sender, PingCompletedEventArgs e)
{
    UpdateGridWithReply(e.Reply);
}

private void UpdateGridWithReply(Reply reply)
{
    if (dataGridView1.InvokeRequired)
    {
        UpdateGridThreadHandler handler = UpdateGridWithReply;
        dataGridView1.BeginInvoke(handler, table);
    }
    else
    {
        DataGridViewRow row = this.current_row; 
        DataGridViewCell speed_cell = row.Cells["speed"];
        speed_cell.Value = reply.RoundtripTime;
    }
}
person kaj    schedule 17.03.2012
comment
Благодаря ви, аз съм начинаещ в c#. Това е полезен пример за мен да използвам делегат. - person yiqun; 17.03.2012