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

为什么每个应用程序运行 5 秒钟没有响应,并且停止按钮无法单击?

为什么每个应用程序运行 5 秒钟没有响应,并且停止按钮无法单击?

C#
元芳怎么了 2022-01-09 10:57:04
我想用开始和停止按钮制作 Pinger,我从这个论坛获得的这段代码就像 stopLoop:private bool _stopLoop;private void button1_Click(object sender, EventArgs e){    _stopLoop = false;    for (int i = 0; i < 100000 && !_stopLoop; ++i)    {        using (Ping p = new Ping())        {            lbPing.Text = p.Send(tbUrl.Text).RoundtripTime.ToString() + "ms\n";            lbPing.Update();        }    }}protected override void WndProc(ref Message m){    switch (m.Msg)    {        case 0x84:            base.WndProc(ref m);            if ((int)m.Result == 0x1)                m.Result = (IntPtr)0x2;            return;    }    base.WndProc(ref m);}private void btStop_Click(object sender, EventArgs e){    _stopLoop = true;}
查看完整描述

3 回答

?
HUH函数

TA贡献1836条经验 获得超4个赞

只需使用asyncandawait模式来释放 UI


private async void button1_Click(object sender, EventArgs e)

{

   _stopLoop = false;


   while( !_stopLoop)

   {  

      using (var p = new Ping())

      {

         var pingReply = await p.SendPingAsync(IPAddress.Parse("1.1.1.1"), 10000);

         lbPing.Text = $"{pingReply.RoundtripTime} ms";

         await Task.Delay(1000);

      }

   }

}

其他资源

SendPingAsync(IPAddress, Int32)

将带有指定数据缓冲区的 Internet 控制消息协议 (ICMP) 回显消息发送到具有指定 IPAddress 的计算机,并作为异步操作从该计算机接收相应的 ICMP 回显应答消息。此重载允许您为操作指定超时值。

参数

  • 地址 IPAddress

标识作为 ICMP 回显消息目标的计算机的 IP 地址。

  • 暂停 Int32

等待 ICMP 回显回复消息的最大毫秒数(在发送回显消息之后)。


查看完整回答
反对 回复 2022-01-09
?
Cats萌萌

TA贡献1805条经验 获得超9个赞

我认为您的停止按钮不起作用,因为您的:

loop= for (int i = 0; i < 100000 && !_stopLoop; ++i)

在这个循环_stopLoop变量中总是true因为你使用了!Operator。


查看完整回答
反对 回复 2022-01-09
?
慕姐8265434

TA贡献1813条经验 获得超2个赞

因为负责处理窗口消息(您的按钮单击)的执行线程正忙于执行您编写的代码。您的代码阻止(阻止)线程返回到保持 UI 响应交互的正常工作。这是我们在编写 Windows 应用程序时必须考虑的常见问题,而不是阻塞(保持忙碌)开始执行按钮单击处理程序中的代码的线程。简单来说,您必须让进入您的点击处理程序的线程尽快再次退出。在您的情况下,您已将其发送到一个不会在 5 秒内返回到您的代码的方法中,而您需要做的是使用它来开始单独执行长时间运行的方法,然后让它返回处理 UI 更新

我们通过异步运行工作代码或使用一种为它创建[类似的]单独线程的机制来做到这一点

使用异步:https : //docs.microsoft.com/en-us/windows/uwp/debug-test-perf/keep-the-ui-thread-responsive

使用 backgroundworker:如何使用 BackgroundWorker?

(我故意避免链接任何鼓励您直接创建和管理自己的线程的东西。以上两种机制更适合现代应用程序)

作为附带信息,Windows 本质上是通过具有消息队列(先进先出)的应用程序工作的。您所做的一切(移动鼠标、单击、按键)都会发布到此队列中,并且您的程序有一个线程处理事件并对其进行操作。如果您在执行代码时让该线程忙几秒钟,它就不会消耗消息。操作系统注意到队列越来越长,并淡化窗口/在标题中放置“无响应”。一旦 ui 线程没有你的代码,它就会消耗消息,你的应用程序就会再次活跃起来。


查看完整回答
反对 回复 2022-01-09
  • 3 回答
  • 0 关注
  • 186 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号