Что не так с моим кодом (SendPingAsync)

Я пишу C# Ping-приложение. Я начал с synchronous Ping-метода, но понял, что пинг нескольких серверов одним кликом занимает все больше и больше времени. Поэтому я решил попробовать метод asynchronous.

Кто-нибудь может мне помочь?

public async Task<string> CustomPing(string ip, int amountOfPackets, int sizeOfPackets)
{
    // timeout
    int Timeout = 2000;
    // PaketSize logic
    string packet = "";
    for (int j = 0; j < sizeOfPackets; j++)
    {
        packet += "b";
    };
    byte[] buffer = Encoding.ASCII.GetBytes(packet);
    // time-var
    long ms = 0;
    // Main Method
    using (Ping ping = new Ping())
        for (int i = 0; i < amountOfPackets; i++)
        {
            PingReply reply = await ping.SendPingAsync(ip, Timeout, buffer);
            ms += reply.RoundtripTime;
        };
    return (ms / amountOfPackets + " ms");
};

Я определил класс «Сервер» (IP или хост, город, страна).

Затем я создаю «серверный» список:

List<Server> ServerList = new List<Server>()
            {
                new Server("www.google.de", "Some City,", "Some Country")
};

Затем я перебираю этот список и пытаюсь вызвать метод следующим образом:

foreach (var server in ServerList)
ListBox.Items.Add("The average response time of your custom server is: " + server.CustomPing(server.IP, amountOfPackets, sizeOfPackets));

К сожалению, это намного более конкурентоспособно, чем метод synchronous, и в тот момент, когда мой метод должен возвращать значение, он возвращает

System.Threading.Tasks.Taks`1[System.string]

Пожалуйста, добавьте свой код, где вы вызываете этот метод. Если метод, в котором вызывается этот метод, не является методом async, вам нужно будет использовать CustomPing.Result для запуска асинхронного метода как синхронного.

Ryan Wilson 27.07.2019 20:33

Многозадачность любого рода действительно намного сложнее простого синхронного программирования. Это большая проблема программирования наших дней. К сожалению, очень неясно, можно ли даже решить простой ответ. Что касается начала работы в многозадачности, я советую использовать (t)ржавый фоновый рабочий. Он устарел и все еще использует отдельные потоки в 100% случаев, но это действительно помогает разобраться с шаблонами.

Christopher 27.07.2019 20:35

Является ли возвращаемое значение строковым представлением объекта, а не значением?

AFM-Horizon 27.07.2019 20:41
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
324
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Класс System.Threading.Tasks.Task<TResult> — это вспомогательный класс для многозадачности. Хотя он находится в пространстве имен Threading, он также работает для многозадачности без потоков. Действительно, если вы видите, что функция возвращает задачу, вы обычно можете использовать ее для любой формы многозадачности. Задачи очень независимы в том, как они используются. Вы даже можете запускать его синхронно, если не возражаете против небольших дополнительных накладных расходов, связанных с тем, что задача не выполняет много задач.

Задача помогает с некоторыми из наиболее важных правил/конвенций многозадачности:

  • Не проглатывайте исключения случайно. Многозадачность Threadbase, как известно, хороша именно в этом.
  • Не использовать результат после отмены

Он делает это, бросая вам исключения (обычно совокупные), если вы пытаетесь получить доступ к Свойство результата, когда соглашение говорит нам, что вы не должны этого делать.

А также наличие всех других полезных свойств для многозадачности.

Ответ принят как подходящий

поскольку у вас есть асинхронный метод, он вернет задачу при вызове следующим образом:

Task<string> task = server.CustomPing(server.IP, amountOfPackets, sizeOfPackets);

когда вы добавляете его непосредственно в свой ListBox, объединяя его со строкой, он будет использовать метод ToString, который по умолчанию печатает полное имя класса объекта. Это должно объяснить ваш вывод:

System.Threading.Tasks.Taks`1[System.string]

Часть [System.string] фактически сообщает вам тип возвращаемого результата задачи. Это то, чего вы хотите, и чтобы получить это, вам нужно дождаться этого! как это:

foreach (var server in ServerList)
   ListBox.Items.Add("The average response time of your custom server is: " + await server.CustomPing(server.IP, amountOfPackets, sizeOfPackets));

1) это нужно сделать другим async методом и

2) это испортит всю параллель, к которой вы стремитесь. Потому что он будет ждать завершения каждого вызова метода.

Что вы можете сделать, так это запустить все задачи одну за другой, собрать возвращающиеся задачи и дождаться их завершения. Предпочтительно, чтобы вы сделали это с помощью асинхронного метода, такого как обработчик кликов:

private async void Button1_Click(object sender, EventArgs e)
{
    Task<string> [] allTasks = ServerList.Select(server => server.CustomPing(server.IP, amountOfPackets, sizeOfPackets)).ToArray();
    // WhenAll will wait for all tasks to finish and return the return values of each method call
    string [] results = await Task.WhenAll(allTasks);
    // now you can execute your loop and display the results:
    foreach (var result in results)
    {
        ListBox.Items.Add(result);
    }

}

Я изменил решение, и оно отлично работает, большое спасибо!

user11075239 14.08.2019 21:13

Другие вопросы по теме