【问题标题】:Timer Won't Stop计时器不会停止
【发布时间】:2014-09-05 18:01:16
【问题描述】:

我编写了这个程序来自动收集允许我连接到端口 8888 的 IP 地址。

在最后一个循环之前它工作正常。我的for 循环由此完成。但是我的计时器一直在输出:

10.10.10.150 - No
10.10.10.150 - No
10.10.10.150 - No
10.10.10.150 - No

这是我的代码,在 for 循环之后我尝试停止计时器,但它并没有停止。

protected void PingPython(){

    for (int i = 50; i <= 150; i++){

        // Try Connect to Python
        try{
            ip = "10.10.10."+i.ToString();

            // Set timer to break Client connection
            tConnectTimeout = new System.Timers.Timer(100);
            tConnectTimeout.Elapsed += new System.Timers.ElapsedEventHandler(tConnectTimeout_Elapsed);
            tConnectTimeout.Start();

            // Connect to Client
            cli = new TcpClient();
            cli.Connect(ip, 8888);

            // If it connects, stop the thread
            tConnectTimeout.Stop();
            tConnectTimeout.Dispose();
            Console.WriteLine(ip + " - Yes");
            ipAddresses.Add(ip);
            cli.Close();

        } catch (ObjectDisposedException ex) {
        } catch (SocketException ex) {
            tConnectTimeout.Stop();
            tConnectTimeout.Dispose();
            Console.WriteLine(ip + " - No");
        }

    }

    tConnectTimeout.Stop();
    btnStart.Sensitive = true;
    foreach(string ipa in ipAddresses){
        cbAddresses.AppendText(ipa);
    }
    cbAddresses.Sensitive = true;
}

public void tConnectTimeout_Elapsed(object sender, System.Timers.ElapsedEventArgs e){
    //Close the socket
    cli.Close();
    Console.WriteLine(ip + " - No");

    //Stop and dispose timer
    tConnectTimeout.Stop();
    tConnectTimeout.Dispose();
}

【问题讨论】:

  • 请添加一个显示问题答案的答案,而不是重新编辑问题。谢谢
  • 您真的只是想实现连接超时吗? stackoverflow.com/a/17118710/56778 以获得更清洁的方式。

标签: c# multithreading timer mono gtk#


【解决方案1】:

从 OPs 编辑中,答案是将 catch 块更改为以下内容:

    } catch (ObjectDisposedException ex) {
        //HERE WAS THE PROBLEM. Added these two lines and now working.
        tConnectTimeout.Stop();
        tConnectTimeout.Dispose();
    } catch (SocketException ex) {
        tConnectTimeout.Stop();
        tConnectTimeout.Dispose();
        Console.WriteLine(ip + " - No");
    }

(见here

但是,我不建议使用此修复程序而不是正确使用 using 来管理计时器。

【讨论】:

  • @JohnNicholas。不——绝对。已经说清楚了 - 至少只是想正确地清理问题。
【解决方案2】:

尝试使用 using 语句来创建计时器(无论异常如何都将其丢弃)

using (var timer = new system.timer)
{




}

而不是使用异常处理程序来执行此操作。 还有为什么空的异常处理程序围绕着一个巨大的范围?这很糟糕,您希望将其删除或限制在尽可能小的范围内..

正在发生的事情是发生了一些事情,导致您的 for 循环在计时器停止之前退出有效,因此它会继续触发事件。

响应乔恩·埃杰顿,解决方案应该是

protected void PingPython(){

for (int i = 50; i <= 150; i++){

    // Try Connect to Python
    try{
        ip = "10.10.10."+i.ToString();

        // Set timer to break Client connection
        tConnectTimeout = new System.Timers.Timer(100);
        tConnectTimeout.Elapsed += new System.Timers.ElapsedEventHandler(tConnectTimeout_Elapsed);
        tConnectTimeout.Start();

        // Connect to Client
        cli = new TcpClient();
        cli.Connect(ip, 8888);


        Console.WriteLine(ip + " - Yes");
        ipAddresses.Add(ip);
        cli.Close();

    } catch (ObjectDisposedException ex) {
    } catch (SocketException ex) {
        Console.WriteLine(ip + " - No");
    }
    finally
    {
         tConnectTimeout.Stop();
         tConnectTimeout.Dispose();
    }

}

tConnectTimeout.Stop();
btnStart.Sensitive = true;
foreach(string ipa in ipAddresses){
    cbAddresses.AppendText(ipa);
}
cbAddresses.Sensitive = true;

}

或者更好

for (int i = 50; i <= 150; i++)
{

    // Try Connect to Python
    try
    {
        ip = "10.10.10."+i.ToString();

        // Set timer to break Client connection
        using( tConnectTimeout = new System.Timers.Timer(100))
        {
            tConnectTimeout.Elapsed += new System.Timers.ElapsedEventHandler(tConnectTimeout_Elapsed);
            tConnectTimeout.Start();

            // Connect to Client
             using (cli = new TcpClient())
             {
                 cli.Connect(ip, 8888);

                 tConnectTimeout.Stop()

                 Console.WriteLine(ip + " - Yes");
                 ipAddresses.Add(ip);
                 cli.Close();
             }
        }
    } 
    catch (ObjectDisposedException ex) 
    {
    } 
    catch (SocketException ex) 
    {
        Console.WriteLine(ip + " - No");
    }
}

【讨论】:

  • 原来是空异常处理程序给了我这个问题。最终 IP 给出了该错误,而该错误又没有关闭线程。我已将 Thread.Close() 添加到该异常中,现在它可以工作了。
  • 是的,很抱歉应该立即看到您应该在 dispose 模式中使用 usings
  • Empty Handler 之所以存在,首先是因为如果不存在,应用程序将立即关闭。
  • @RussellHickey: @JohnNicholas 是对的——你最好使用using 模式来处理一次性用品
  • 您确实应该将尝试的范围缩小到可能失败的部分。如果你不这样做,你会让你的生活更艰难。事情可能很难追踪。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 2023-02-23
  • 1970-01-01
  • 1970-01-01
  • 2012-08-09
  • 1970-01-01
相关资源
最近更新 更多