尝试为背景工作者计时并在需要很长时间时将其取消

时间:2013-12-05 13:25:29

标签: c# timer backgroundworker

我正在解析C#应用程序中的网页,我希望能够计算所需的时间并在超过一定时间时取消它。我查看了两个Timer类,我还在画一个空白。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

我希望这会帮助你

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();
        }
    }
}

答案 1 :(得分:1)

这里有两个问题:

  • 在一段时间后生成取消请求
  • 取消解析操作

对于第一个你可以使用Timer,如你所说,(实际上有三个'Timer'类) - 最能给你成功的是System.Threading.Timer。对此的回调将在池线程上发生,因此即使您的解析操作仍在运行,也应该发生。 (在担心实际取消之前,使用Debug.Print或调试器使其工作。)

对于第二部分,你需要有一些方法来告诉你的解析过程放弃 - 这可能是一个CancellationToken,一个全局变量或一个WaitEvent - 有很多选项,但是很难建议最好的一个,不了解你的解析过程以及你对代码的访问权限。

当然,如果您有足够的权限访问解析代码以添加取消检查,那么您可以进行if(DateTime.UtcNow > _timeoutAt)测试,在这种情况下您不需要独立计时器...(如果不明显,则在开始解析操作之前设置_timeoutAt = DateTime.UtcNow.AddSeconds(xxx)