猿问

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

我想用开始和停止按钮制作 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;

}


元芳怎么了
浏览 187回答 3
3回答

HUH函数

只需使用asyncandawait模式来释放 UIprivate async void button1_Click(object sender, EventArgs e){&nbsp; &nbsp;_stopLoop = false;&nbsp; &nbsp;while( !_stopLoop)&nbsp; &nbsp;{&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; using (var p = new Ping())&nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var pingReply = await p.SendPingAsync(IPAddress.Parse("1.1.1.1"), 10000);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lbPing.Text = $"{pingReply.RoundtripTime} ms";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;await Task.Delay(1000);&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp;}}其他资源SendPingAsync(IPAddress, Int32)将带有指定数据缓冲区的 Internet 控制消息协议 (ICMP) 回显消息发送到具有指定 IPAddress 的计算机,并作为异步操作从该计算机接收相应的 ICMP 回显应答消息。此重载允许您为操作指定超时值。参数地址&nbsp;IPAddress标识作为 ICMP 回显消息目标的计算机的 IP 地址。暂停&nbsp;Int32等待 ICMP 回显回复消息的最大毫秒数(在发送回显消息之后)。

Cats萌萌

我认为您的停止按钮不起作用,因为您的:loop=&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;100000&nbsp;&&&nbsp;!_stopLoop;&nbsp;++i)在这个循环_stopLoop变量中总是true因为你使用了!Operator。

慕姐8265434

因为负责处理窗口消息(您的按钮单击)的执行线程正忙于执行您编写的代码。您的代码阻止(阻止)线程返回到保持 UI 响应交互的正常工作。这是我们在编写 Windows 应用程序时必须考虑的常见问题,而不是阻塞(保持忙碌)开始执行按钮单击处理程序中的代码的线程。简单来说,您必须让进入您的点击处理程序的线程尽快再次退出。在您的情况下,您已将其发送到一个不会在 5 秒内返回到您的代码的方法中,而您需要做的是使用它来开始单独执行长时间运行的方法,然后让它返回处理 UI 更新我们通过异步运行工作代码或使用一种为它创建[类似的]单独线程的机制来做到这一点使用异步:https&nbsp;:&nbsp;//docs.microsoft.com/en-us/windows/uwp/debug-test-perf/keep-the-ui-thread-responsive使用 backgroundworker:如何使用 BackgroundWorker?(我故意避免链接任何鼓励您直接创建和管理自己的线程的东西。以上两种机制更适合现代应用程序)作为附带信息,Windows 本质上是通过具有消息队列(先进先出)的应用程序工作的。您所做的一切(移动鼠标、单击、按键)都会发布到此队列中,并且您的程序有一个线程处理事件并对其进行操作。如果您在执行代码时让该线程忙几秒钟,它就不会消耗消息。操作系统注意到队列越来越长,并淡化窗口/在标题中放置“无响应”。一旦 ui 线程没有你的代码,它就会消耗消息,你的应用程序就会再次活跃起来。
随时随地看视频慕课网APP
我要回答