REG线程:如何实现这一点

时间:2011-02-28 07:48:34

标签: c# multithreading

我有一个具有backgroundWorker线程的Winform应用程序,并且只通过它执行所有操作。

在完成一个特定的操作,即连接到服务器之后,我想创建一个监视器来检查与服务器的连接是否存在。将执行Web服务以找出连接并检查结果以了解。如果没有重新连接。我相信我应该创建一个监控连接的线程。逻辑如下:在每个X秒监视器检查连接后,再次在X秒后返回并再次完成其工作,即检查连接并了解状态。我认为他们不需要阻止线程,因为每当我得到结果时我都能做出反应。我也不需要在这个过程中处理任何UI。可能只需要一次我发现连接丢失,然后必须调用其他重新连接的功能,这个线程再次重启或类似的东西。

我阅读了2-3篇教程,但无法弄清楚如何实现这一点 - 使用和调用哪种线程类型。

实施表格代码:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e){    
    if (currentState == OPENING)
         LoadAfterLogin();
    else if (currentState == CONNECTING)
         Connect();    // CONNECTS TO THE SERVER
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e){
    ......   
    else if (value == CONNECTED)   {
        currentState = CONNECTED;
        statusLabel.Text = "CONNECTED Successfully to server";
       //  HERE MONITOR THREAD SHOULD BE STARTED ONCE APP KNOWS FOR SURE, THAT IT IS CONNECTED TO SERVER    
       monitorConn = new MonitorConnection();   
   } else if (value == EXP)   {
       currentState = ERR_CONNECTING;
       ExceptionData ed = (ExceptionData)e.UserState;
        .....   
   }
}

////////////////////////////////////////ANOTHER MonitorConnection thread class 

public class MonitorConnection : Thread{
private DateTime startTime, lastCheckedTime;
private bool conneced;
private int intervalDuration, nextTime;

public MonitorConnection()    {
    intervalDuration = 10000;    
}
public bool IsConneced    {
    get { return conneced; }
    set { conneced = value; }
}

// SHOULD CALL THIS WHEN THE THREAD IS STARTED
public void start()    {
    startTime = DateTime.Now;
    nextTime = DateTime.Now;
}

// THIS SHOULD BE SOMEHOW CALLED BY run()
public void checkConnection()    { 
   // IS CURRENT TIME IS >= SCHEDULED NEXTTIME
    if (DateTime.Now >= nextTime) {
        // Checks if the connection to server is alive or not
        conneced = UltimateLibrary.http.HTTPUtility.isConnectionAvailable();
        lastCheckedTime = DateTime.Now;
        nextTime = lastCheckedTime + intervalDuration;
    }
}

// SOMETHING LIKE RUN - that starts the process execution
public void run() {
   while (true) {
        if (DateTime.Now >= nextTime)
            checkConnection();
        Thread.sleep(interval); 
   }
}

}

这是已经实现的代码,用于显示我想要实现的逻辑。我同意并且知道代码并不完全符合它的标记。仍然需要通过不阻塞,连续间隔运行等来使其变得正确。我认为应该扩展一些除Thread以外的其他类(不确定哪一个是合适的)。

非常感谢任何帮助。任何人都可以给我一些提示/想法来实现上述。

[EDITED:] 感谢Vinay,根据您的代码,我实现如下: - 在MonitorConnection类中创建了一个Timer obj。

        public void StartMonitor()
        {
            startTime = DateTime.Now;
            nextTime = DateTime.Now;
            timer = new Timer(intervalDuration);
            timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            GC.KeepAlive(timer);    // I don't think this is reqd as timer is a member of class
            timer.Start();   // Can also call timer.Enabled = true;
        }

    public static void checkConnection()
    {
        if (DateTime.Now >= nextTime) {
            // Checks if the connection to server is alive or not
            connected = UltimateLibrary.http.HTTPUtility.isConnectionAvailable();
            lastCheckedTime = DateTime.Now;
            nextTime = lastCheckedTime.AddMilliseconds(intervalDuration);
        }

    }

    private static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        // Check if connection is alive
        checkConnection();
    }

。 如果连接是假的,即服务器没有连接,那么必须让调用表知道这一点。我想这可以将表格的对象传递给这个类,并在连接== false时调用它各自的方法。你说什么 ?这和上面的代码似乎是正确的吗?我们非常感谢您的指导。 - 谢谢

谢谢

1 个答案:

答案 0 :(得分:0)

为什么不使用Timer - 它非常简单易用。例如,

    public event EventHandler Disconnected;


    timer = new System.Timers.Timer(10000);
    timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
    timer.Enabled = true;

    ...

    private static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
       // check if connection is alive
       conneced = UltimateLibrary.http.HTTPUtility.isConnectionAvailable();
       if (!connected)
       { 
          // inform listeners
          var listener = Disconnected;
          if (null !- listener)
          {
              Disconnected(EventArgs.Empty);
          }
       }
    }

只需要注意确保定时器被引用所需的持续时间(否则将被垃圾收集)。