Я пишу 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]
Многозадачность любого рода действительно намного сложнее простого синхронного программирования. Это большая проблема программирования наших дней. К сожалению, очень неясно, можно ли даже решить простой ответ. Что касается начала работы в многозадачности, я советую использовать (t)ржавый фоновый рабочий. Он устарел и все еще использует отдельные потоки в 100% случаев, но это действительно помогает разобраться с шаблонами.
Является ли возвращаемое значение строковым представлением объекта, а не значением?





Класс System.Threading.Tasks.Task<TResult> — это вспомогательный класс для многозадачности. Хотя он находится в пространстве имен Threading, он также работает для многозадачности без потоков. Действительно, если вы видите, что функция возвращает задачу, вы обычно можете использовать ее для любой формы многозадачности. Задачи очень независимы в том, как они используются. Вы даже можете запускать его синхронно, если не возражаете против небольших дополнительных накладных расходов, связанных с тем, что задача не выполняет много задач.
Задача помогает с некоторыми из наиболее важных правил/конвенций многозадачности:
Он делает это, бросая вам исключения (обычно совокупные), если вы пытаетесь получить доступ к Свойство результата, когда соглашение говорит нам, что вы не должны этого делать.
А также наличие всех других полезных свойств для многозадачности.
поскольку у вас есть асинхронный метод, он вернет задачу при вызове следующим образом:
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);
}
}
Я изменил решение, и оно отлично работает, большое спасибо!
Пожалуйста, добавьте свой код, где вы вызываете этот метод. Если метод, в котором вызывается этот метод, не является методом
async, вам нужно будет использоватьCustomPing.Resultдля запуска асинхронного метода как синхронного.