[英]Trying to time a backgroundworker and cancel it if it takes to long
我正在C#应用程序中解析网页,我希望能够计时所需的时间,如果超过一定的时间,则可以将其取消。 我研究了两个Timer类,但仍处于空白状态。 任何帮助将不胜感激。
希望这对您有帮助
using System;
using System.ComponentModel;
using System.Threading;
namespace ConsoleApplication1
{
internal class Program
{
private static BackgroundWorker worker;
private static Timer workTimer;
private static void Main(string[] args)
{
Console.WriteLine("Begin work");
worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.WorkerSupportsCancellation = true;
worker.WorkerReportsProgress = true;
worker.RunWorkerAsync();
// Initialize timer
workTimer = new Timer(Tick, null,
new TimeSpan(0, 0, 0, 10), // < Amount of time to wait before the first tick.
new TimeSpan(0, 0, 0, 10)); // < Tick every 10 second interval
Console.ReadLine();
}
private static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
workTimer.Dispose();
if (e.Cancelled) return;
// Job done before timer ticked
Console.WriteLine("Job done");
}
private static void worker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 12; i++)
{
// Cancel the worker if cancellation is pending.
if (worker.CancellationPending)
{
e.Cancel = true;
break;
}
Console.WriteLine(i);
Thread.Sleep(1000);
}
}
private static void Tick(object state)
{
// Stop the worker and dispose of the timer.
Console.WriteLine("Job took too long");
worker.CancelAsync();
worker.Dispose();
workTimer.Dispose();
}
}
}
这里有两个问题:
第一次,您可以按照您的建议使用Timer(实际上有三个“ Timer”类)-System.Threading.Timer是最可能给您带来成功的机会。 为此的回调将在池线程上发生,因此即使您的解析操作仍在运行,它也应该发生。 (在担心实际取消之前,请使用Debug.Print或调试器进行此操作。)
对于第二部分,您需要有一些方法来告诉您的解析过程放弃-这可以是CancellationToken,全局变量或WaitEvent-有很多选项,但是很难提出最好的选择进一步了解您的解析过程以及对其代码的访问权限。
当然,如果您有足够的权限来解析代码以添加取消检查,则可以只进行if(DateTime.UtcNow > _timeoutAt)
测试,在这种情况下,您不需要独立的计时器...(如果不太明显,您可以在开始解析操作之前设置_timeoutAt = DateTime.UtcNow.AddSeconds(xxx)
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.