【问题标题】:Ping ASync ProblemsPing 异步问题
【发布时间】:2017-02-16 11:48:52
【问题描述】:

我必须在下面指示的行上有一个断点才能使以下代码正常工作。否则,程序将无限期暂停。

    async Task<List<PingReply>> PingAsync()
    {
        var pingTargetHosts = GetIPs();
        var pingTasks = pingTargetHosts.Select(host => new Ping().SendPingAsync(host, 2000)).ToList();
        var pingResults = await Task.WhenAll(pingTasks); //THIS LINE NEEDS A BREAKPOINT TO WORK
        return pingResults.ToList();
    }

代码是这样调用的

        List<PingReply> GetReplies()
    {
        var PingIPs = PingAsync();
        MessageBox.Show("Loading:...");
        List<PingReply> Results = PingIPs.Result;
        return Results;
    }

谁能告诉我我需要如何修改我的代码才能删除断点,但仍然有一段功能代码。

编辑: 未经测试,但 99% 肯定这会起作用。

async Task<List<PingReply>> PingAsync()
    {
        var pingTargetHosts = GetIPs();
        var pingTasks = pingTargetHosts.Select(async host => await new Ping().SendPingAsync(host, 2000)).ToList();
        var pingResults = await Task.WhenAll(pingTasks);
        return pingResults.ToList();
    }

    async Task<List<PingReply>> GetReplies()
    {
        var PingIPs = PingAsync();
        MessageBox.Show("Loading:...");
        return await PingIPs;
    }

    async Task BuildDictionary()
    {
        List<PingReply> Replies = await GetReplies();
        //Use this list via foreach
    }
    async private void button1_Click(object sender, EventArgs e)
    {
        EthernetCheck checker = new EthernetCheck();
        checker.Check();
        bool IsEthernetIn = checker.PluggedIn;
        if (IsEthernetIn)
        {
            await BuildDictionary();
            //Do Stuff
        }           
    }

【问题讨论】:

  • Thread.Sleep 可以提供帮助
  • “断点”是什么意思? await Task.WhenAll 不需要任何断点即可工作
  • 您的代码本身导致了阻塞。您正在调用await,而您已经.Result 阻塞了UI 线程。您的GetReplies 方法本身应该是异步的,即async Task&lt;List&lt;PingReply&gt;&gt; GetReplies(){MessageBox.Show();return await PingAsync();}
  • 谁打电话给GetReplies?如果调用以事件处理程序开始,则应使事件处理程序之前的所有方法都是异步的。事件处理程序本身应该是async void
  • 和任何异步方法一样var Replies=await GetReplies();

标签: c# asynchronous ping


【解决方案1】:

因为您是blocking on asynchronous code,所以您的代码处于死锁状态。要修复它,请使用async all the way:

async Task<List<PingReply>> GetRepliesAsync()
{
  var PingIPs = PingAsync();
  MessageBox.Show("Loading:...");
  return await PingIPs;
}

用法:

var replies = await GetRepliesAsync();

【讨论】:

  • async void BuildDictionary() { var Replies = await GetReplies(); 是我应该做的,我想。不幸的是,我将无法在一周内对此进行测试。
  • @LukeIreland:不;你应该避免async void。请改用async Task
  • 它们产生相同的结果/效果吗?你能解释一下区别吗?我读了你的两篇文章,但仍然不是 100%。我已经更新了我的主要帖子中的“原型”以包含异步任务。 @斯蒂芬克莱里
  • @LukeIreland:你的新代码看起来不错。我解释了my async best practices article 的区别——特别是async void 具有难以处理的异常处理行为。
  • 当“一直异步”时,它会上升到一个按钮单击事件,这会弄乱我的所有代码。如何分离这些代码部分。
【解决方案2】:

在使用 async/await 时,你应该记住 .net 框架会控制程序执行的流程,所以我建议你将所有调用都设为异步以避免此类问题。

async Task<List<PingReply>> PingAsync()
{
    var pingTargetHosts = await GetIPs();
    var pingTasks = pingTargetHosts.Select(host => await new Ping().SendPingAsync(host, 2000)).ToList();
    var pingResults = await Task.WhenAll(pingTasks);
    return pingResults.ToList();
}

【讨论】:

  • 为什么只在 GetIP 上使用 await 来生成列表?它返回List&lt;IPAddress&gt;。另外,我在var pingTasks= 行中添加等待需要在主机之前异步。我现在无法测试这个,因为我在家,我会告诉你这是否有效。谢谢。
  • 让我们知道它是否有效或者您是否找到了其他解决方案。谢谢你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-09
  • 2017-12-31
  • 1970-01-01
  • 2010-12-16
  • 2014-10-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多