Использование класса NetworkAvailabilityEventArgs


#1

С наступившим 2019 г. всех!

При исползовании класса NetworkAvailabilityEventArgs, после компиляции получаю сообщение: (38) : Ни один конструктор не найден. Хотя класс Ping “подхватился”… Не могли бы вы указать мне правильное обращение к классу NetworkAvailabilityEventArgs?

var
  IPaddr: string;
begin
  var HPing := new System.Net.NetworkInformation.Ping();
  **var avNet := new System.Net.NetworkInformation.NetworkAvailabilityEventArgs();**
  IPaddr := '100.100.100.24';
  var RPing := HPing.Send(IPaddr);
  if RPing.Status = IPStatus.Success then 
    textBox1.Text := RPing.Status.ToString 
  else
    textBox1.Text := 'Failed';
end;

#2
  1. Выделять код надо так:

```
код
```

Знак ` находится за Ё в англ. раскладке.

  1. Все ***EventArgs классы - это хранилища для информации об эвенте.
    Чтоб узнать подробнее - ищем этот класс на msdn.

    Оттуда пара-тройка ссылок и получаете всю нужную инфу о том как обрабатывать эвенты изменения состояния сети.

#3

Не получается… Делегированием и конструкторами совсем запутался. Вроде простой, но столько времени потратил.

procedure AvNet(sender:object; e:System.Net.NetworkInformation.NetworkAvailabilityEventArgs);
begin
end;

begin
    var NetEv := new System.Net.NetworkInformation.NetworkAvailabilityChangedEventHandler(AvNet);
    TextBox1.Text := NetEv.isAvailable.ToString;
end.

Вроде так представляю, но увы… :disappointed:


#4

Вы знаете английский хоть на каком то уровне? Если нет - стоит выучить. А пока что используйте гугл переводчик:

Всегда читайте раздел Remarks. Вот последняя часть, которую я выделил на этом видео:

This delegate handles NetworkAvailabilityChanged events raised by the NetworkChange class.

Этот делегат обрабатывает эвенты типа NetworkAvailabilityChanged, которые вызываются классом NetworkChange.

Эвенты (события) это особые поля классов, к которым не применима операция := но применимо += и -=. У них всегда тип-делегат (процедурная или функциональная переменная):

type
  t1 = class
    
    event SomethingChanged: procedure(sender: object);
    
    procedure SimulateSC;
    begin
      if SomethingChanged<> nil then
        SomethingChanged(nil);
    end;
    
  end;

procedure p1(o: object);
begin
  writeln(o);
end;

begin
  var a := new t1;
  
  //с помощью лямбды
  a.SomethingChanged += sender->
  begin
    writeln($'был вызван привязанный к SomethingChanged делегат, sender был {_ObjectToString(sender)}');//' *исправление подсветки форума*
  end;
  
  //с помощью обычной процедуры
  a.SomethingChanged += p1;
  a.SomethingChanged -= p1;//его убрали, поэтому не вызовется. с лямбдами не прокатит, потому что каждая лямбда - новый метод
  
  a.SimulateSC;//так не хорошо, эвенты должны вызываться только самим классом. но для теста сойдёт
  
end.

Теперь смотрим на msdn страницу класса NetworkChange, о котором сказано что он вызывает нужный вам эвент. Там, в самом верху, видим раздел Examples, то есть примеры. Примеры надо смотреть на C#, они почти строчка в строчку переводятся на PascalABC.Net:

using System;
using System.Net;
using System.Net.NetworkInformation;

namespace Examples.Net.AddressChanges
{
    public class NetworkingExample
    {
        public static void Main()
        {
            NetworkChange.NetworkAddressChanged += new 
            NetworkAddressChangedEventHandler(AddressChangedCallback);
            Console.WriteLine("Listening for address changes. Press any key to exit.");
            Console.ReadLine();
        }
        static void AddressChangedCallback(object sender, EventArgs e)
        {
            
            NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
            foreach(NetworkInterface n in adapters)
            {
                Console.WriteLine("   {0} is {1}", n.Name, n.OperationalStatus);
            }
        }
    }
}
uses System;
uses System.Net;
uses System.Net.NetworkInformation;

procedure AddressChangedCallback(sender: object; e: EventArgs);
begin
  var adapters := NetworkInterface.GetAllNetworkInterfaces;
  foreach var n: NetworkInterface in adapters do
  begin
    Console.WriteLine('   {0} is {1}', n.Name, n.OperationalStatus);
  end;
end;

begin
  NetworkChange.NetworkAddressChanged +=
  NetworkAddressChangedEventHandler(AddressChangedCallback);
  readln;
end.

Но это пример для NetworkAddressChanged. Для NetworkAvailabilityChanged нет примера, но по тому же принципу:

uses System;
uses System.Net;
uses System.Net.NetworkInformation;

procedure AddressChangedCallback(sender: object; e: NetworkAvailabilityEventArgs);
begin
  writeln($'Соединение с инетом = {e.IsAvailable}');
end;

begin
  NetworkChange.NetworkAvailabilityChanged +=//это 2 из всего 2 эвентов в этом классе сложно пропустить
    AddressChangedCallback;//в паскале преобразование не нужно, в отличии от C#
  
  System.Threading.Thread.CurrentThread.Suspend;//лучше поставить поток на паузу, чтоб небыло этой полосочки которая просит ввод
end.

А если использовать лямбду - не надо писать то длинючие объявление процедуры, которая понадобится только 1 раз:

begin
  System.Net.NetworkChange.NetworkAvailabilityChanged += (o,e)->
  begin
    
    e.IsAvailable.Println;
    
  end;
  
  System.Threading.Thread.CurrentThread.Suspend;
end.

Если какое то то ещё понятие не понятно, вроде эвентов, делегирования и конструкторов - пишите, во всех подробностях объясню.