我的代码(SendPingAsync)有什么问题

时间:2019-07-27 18:31:39

标签: c#

我正在编写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]

2 个答案:

答案 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);
    }

}