为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
忽然笑 2023-07-22 15:45:52
我正在编写一个C#Ping 应用程序。我一开始使用synchronousPing 方法,但我发现一键 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 回答

?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

因为你有一个异步方法,所以当它被调用时它会返回任务,如下所示:


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);

    }


}


查看完整回答
反对 回复 2023-07-22
?
慕哥9229398

TA贡献1877条经验 获得超6个赞

该类System.Threading.Tasks.Task<TResult>是多任务处理的辅助类。虽然它驻留在线程命名空间中,但它也适用于无线程多任务处理。事实上,如果您看到一个函数返回一个任务,您通常可以将它用于任何形式的多任务处理。任务的使用方式非常不可知。如果您不介意任务执行次数不多而带来的额外开销,您甚至可以同步运行它。

任务有助于实现多任务处理的一些最重要的规则/惯例:

  • 不要意外吞下异常。众所周知,线程基多任务处理在这方面做得很好。

  • 取消后请勿使用结果

如果您尝试访问结果属性,而约定告诉我们不应该这样做,那么它会向您抛出异常(通常是聚合异常)来实现这一点。

以及具有多任务处理的所有其他有用属性。


查看完整回答
反对 回复 2023-07-22
  • 2 回答
  • 0 关注
  • 161 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信