我有一些业务逻辑来检查Web服务是否存在。
我想在开始时间后每5分钟重复检查一次。
如何通过任务或线程或等待/异步功能来执行此操作。
答案 0 :(得分: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
我更喜欢线程解决方案,因为从外部进程获取数据有点复杂。将线程数据同步到主线程更容易。您需要通过WCF通过命名管道或套接字通信(TCP / UDP)进行IPC(进程间通信)等范例。
如果您需要提示如何从线程中获取数据:您可以例如在WebserviceChecker类中定义一个事件,当你的WS状态发生变化时,你将会出现这个事件。
关于 IsBackground 事情的一些话......如果你不把线程设置为后台,你的应用程序只会退出,当每个前台线程退出他的worker方法时。后台线程将在应用程序关闭时自动中止。
一个关于ThreadAbortedException的词:在.NET中,我们获得了强制中止线程的特权。框架将在线程方法中的任何位置引发此异常以退出它。如果你没有捕获它,线程将退出而不进行清理。所以抓住它,清理记忆或做一些完成任务。你会这样做:
_watcher.Abort();
欢呼声:)
[edit]在MSDN上有一个很好的多线程教程:http://msdn.microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspx [/ edit]
[edit]如果你想使用System.Threading.Timer,你需要在你的观察者类中实现System.Threading.TimerCallback委托。然后你可以使用句点而不是后台线程来实例化一个新的计时器。有关详细信息,请参阅http://msdn.microsoft.com/de-de/library/system.threading.timercallback.aspx [/ edit]
答案 1 :(得分: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.