【问题标题】:Executing method by timer inside threadpool线程池内定时器的执行方法
【发布时间】:2011-09-30 06:03:52
【问题描述】:

在我的多线程 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);
}

【问题讨论】:

  • 考虑 System.Timers.Timer 已经在其他线程上运行。它不同于 System.Windows.Forms.Timer
  • @Tigran 据我了解,我的解决方案是 Thread.Sleep。
  • 我试过了,效果很好。有没有办法让用户也可以取消 SomeMethod 的执行?
  • Brr,这里不使用 Sleep() 没有意义。

标签: c# .net multithreading timer threadpool


【解决方案1】:

您应该在使用后处理每个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;
    }
}

【讨论】:

  • 我读到 Thread.Sleep() 不适合该任务。不是吗?
  • Thread.Sleep 在后台线程上很好,尽管在更复杂的解决方案(支持取消的解决方案)中我会使用ManualResetEvent,它可以从不同的线程触发。 Thread.Sleep 的唯一问题是,如果你想通知你的后台线程结束,你需要在它唤醒之前等待。
  • 这段代码和他的代码有点不同,因为他的代码有可能在尝试10次后退出,如果它依次失败10次。不知道对他有没有影响。
  • @Tigran:哦,为了简单起见,这只是一个示例。我会更新的。
  • 哦,常见的!我的只是一个评论。没什么重要的 :) 由人来决定是否有所作为。
【解决方案2】:

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

【讨论】:

  • 我只需要调用 SomeMethod 几次,而它执行得不好或调用 count richs allowed number
【解决方案3】:

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

我只会在该委托中创建一个循环,因为它不会阻塞主线程。 Groo 就是一个很好的例子。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-27
    • 2017-12-29
    • 2022-01-18
    • 2021-04-11
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多