在线程池内通过计时器执行方法

时间:2011-07-07 07:56:22

标签: c# .net multithreading timer threadpool

在我的多线程Web应用程序中,我在ThreadPool SomeMethod中调用,这可能会引发异常。假设我想在第一次调用时导致异常时尝试几次。我决定在我的动作中使用System.Timers.Timer进行尝试。我可以使用下面的代码吗?安全吗?

static void Caller()
{
    ThreadPool.QueueUserWorkItem(action =>
        {
            try
            {
                SomeMethod();
                Console.WriteLine("Done.");
            }
            catch
            {
                var t = new System.Timers.Timer(1000);
                t.Start();
                var count = 0;
                t.Elapsed += new System.Timers.ElapsedEventHandler((o, a) =>
                {
                    var timer = o as System.Timers.Timer;
                    count++;
                    var done = false;
                    Exception exception = null;
                    try
                    {
                        Console.WriteLine(count);
                        SomeMethod();
                        done = true;
                    }
                    catch (Exception ex)
                    {
                        exception = ex;
                    }
                    if (done || count == 10)
                    {
                        Console.WriteLine(String.Format("Stopped. done: {0}, count: {1}", done, count));
                        t.Stop();
                        if (!done) throw exception;
                    }
                });
            }
        });
    Thread.Sleep(100000);
}

static void SomeMethod()
{
    var x = 1 / new Random().Next(0, 2);
}

3 个答案:

答案 0 :(得分:2)

您应该在使用后处理每个Timer,这是肯定的。但是,你可能会做一些更简单的事情:

static void Main()
{
    ThreadPool.QueueUserWorkItem(action =>
    {
        while (TrySomeMethod() == false)
            Thread.Sleep(1000);
    });

    // wait here
    Console.Read();
}

static bool TrySomeMethod()
{
    try
    {
         SomeMethod();
         return true;
    }
    catch
    {
         return false;
    }
}

答案 1 :(得分:1)

我不认为在线程池线程中使用计时器是一种安全的方法。我可能错了,但是当线程方法已经完成执行时,计时器将提升其已用事件。在这种情况下,将抛出异常。另外,我没有看到你没有处理导致资源泄漏的计时器。如果您解释为什么需要计时器,我会尝试找到一个安全的解决方案......

答案 2 :(得分:0)

我没有看到在ThreadPool队列中使用Timer的意义,因为ThreadPool会产生一个新线程,而Timer也会产生一个新线程。

我只是在该委托中有一个循环,因为它不会阻止主线程。 Groo展示了一个很好的例子。