2013-03-08 127 views
0

我有一些业务逻辑来检查webservice是否存活。如何在X时间内运行C#任务或线程

我想在开始时间后的每5分钟后反复检查1小时。

如何通过任务或线程或等待/异步功能执行此操作。

+0

[?你尝试过什么(http://whathaveyoutried.com) – 2013-03-08 06:38:49

+0

你的标题是混乱...我怀疑你想要“重复呼叫每X分钟”,而不是...检查出类似的问题 - http://stackoverflow.com/questions/tagged/c%23+timer?sort=faq&pagesize=50 – 2013-03-08 06:40:49

+0

@Alexei我完全不想做什么你在想什么。我想运行一个任务X时间 – 2013-03-08 06:46:28

回答

1

首先,重新检查您的业务需求。这到底会给你带来什么?网络服务可能会在任何时候突然消失,所以您刚刚检查过的事实并不意味着您的下一次通话会成功。所有网络通信都是如此。

因此,如果您有一个单独的“检查器”,则“真实”代码的复杂性不会降低。这种设计的唯一好处是某种视觉通知给用户,他们可以合理地确信他们的下一次服务呼叫将会成功。即使这样你也许会想重新考虑,因为只有合理当然,如果你对他们说谎,用户会生气。

这就是说,你可以使用它Task就像这样做:

private static async Task CheckAsync(CancellationToken token) 
{ 
    // Check your web service. 
    await CheckWebServiceAsync(token); 

    // Wait 5 minutes. 
    await Task.Delay(TimeSpan.FromMinutes(5), token); 
} 

... 

var done = new CancellationTokenSource(TimeSpan.FromHours(1)); 
Task checkingTask = CheckAsync(done.Token); 
// When checkingTask completes: 
// IsCanceled -> One hour passed with no errors. 
// IsFaulted -> The web service failed. 
5

线程解决方案是这样的:

public class WebserviceChecker { 

    private int durationInHours = 1; 
    public void setDuration(int value) { durationInHours = value; } 

    private boolean _shutdown = false; 

    private DateTime _startTime = null; 
    // System.Windows.Forms.Timer 
    private Timer _timer = null; 

    public void CheckWebservice() { 

     _startTime = DateTime.Now; 
     _timer = new Timer(); 
     _timer.Tick += handleTimerTick; 

     while(!_shutdown) { 
      try { 
       // do what ever you want to do for checking your webservice... 
       // ... 
      } catch (ThreadAbortedException ex) { 
       // do cleanup, then 
       // 
       break; 
      } catch (Exception ex) { 
       Logger.Instance.log(LoggerLogType.Type.Err, ex.ToString()); 
      } 
      // wait 5 secs (customize to your needs) 
      Threading.Thread.Sleep(5000); 
     } 

     if(_shutdown) { 
      // do some regular cleanup here... 
     } 

    } // public void CheckWebservice() 

    public void Shutdown() { 
     _shutdown = true; 
    } 

    private void handleTimerTick(Object sender, System.EventArgs e) { 
     TimeSpan ts = _startTime .Subtract(DateTime.Now); 
     if(ts.TotalHours >= durationInHours) { 
      Shutdown(); 
     } 
    } 
} 

,并立即启动后台线程这样的:

WebserviceChecker _c = new WebserviceChecker(); 

Thread _watcher = new Thread(_c.CheckWebservice); 
_watcher.IsBackground = true; 
_watcher.Start(); 

调度任务看这里:C# start a scheduled task

我宁愿因为从外部进程获取数据有点复杂。同步线程数据到你的主线程更容易。您将需要通过命名管道或套接字通信(TCP/UDP)在WCF以上的IPC(内部进程通信)等范例。

如果您需要提示如何从线索中获取数据:您可以在WebserviceChecker类中定义一个事件,当WS发生状态变化时您将升起该事件。

关于的一些词语IsBackground事情......如果您不设置线程为背景,那么当每个前台线程退出其工作方法时,您的应用程序将仅退出。后台线程将在应用程序关闭时自动中止。

ThreadAbortedException:在.NET中,我们获得了硬中止线程的权限。该框架将在线程方法中的任何位置引发此异常以退出它。如果你没有捕获它,线程将会退出而不进行清理。所以只需抓住它,清理内存或完成一些完成任务。你会在这里做这样的:

_watcher.Abort(); 

欢呼ceth :)

[编辑]有在MSDN是一个很好的多线程教程:http://msdn.microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspx [/编辑]

[编辑]如果你想要使用System.Threading.Timer,您需要将System.Threading.TimerCallback委托实现到您的监视器类中。那么你可以使用一段时间来实例化一个新的定时器,而不是后台线程。请参阅http://msdn.microsoft.com/de-de/library/system.threading.timercallback.aspx了解更多详情

+0

您的Timer类的System.Threading或system.Timers.Timer – 2013-03-08 09:36:58

+0

System.Windows.Forms.Timer的 – ceth 2013-03-08 10:16:53

相关问题