我正在编写C#
Ping应用程序。
我从synchronous
Ping方法开始,但是我发现一次单击即可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]
答案 0 :(得分:0)
类System.Threading.Tasks.Task<TResult>
是多任务处理的帮助类。虽然它位于线程命名空间中,但它也适用于无线程多任务处理。确实,如果看到函数返回任务,通常可以将其用于任何形式的多任务处理。任务的使用方式非常不可知。如果您不介意执行Task不会带来太多额外开销,甚至可以同步运行它。
任务有助于解决多任务处理的一些最重要的规则/要求:
如果您在惯例告诉我们您不应该这样做时尝试访问Result Property,则会通过在您的脸上抛出异常(通常是汇总异常)来做到这一点。
具有用于多任务处理的所有其他有用的属性。
答案 1 :(得分:0)
由于您有一个异步方法,因此它将在调用时返回任务:
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)这将弄乱您想要的所有并行性。因为它将等待每个方法调用完成。
您可以做的是一个接一个地启动所有任务,收集返回的任务,然后等待所有任务完成。最好使用异步方法(例如clickhandler)来做到这一点:
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);
}
}