【问题标题】:How wrong is the using of such code使用这样的代码有多么错误
【发布时间】:2011-10-21 19:12:13
【问题描述】:

我得到了一个调用异步块的代码。

    private delegate void MyDelegate();
    void Async(MyDelegate t) {
        Thread thread = new Thread(new ThreadStart(t));
        thread.IsBackground = true;
        thread.Start();
    }

然后:

Async(delegate() {
    // code
});

我正在使用它,但我确信这不是正确的方法。这种方法有什么问题?

【问题讨论】:

  • 假设您只想启动一个运行某个委托的新线程,这是一个完美的解决方案。你为什么认为这是错误的,你想要完成什么?
  • 我不确定它是否错了,但是每次我想要一些东西不阻止我的 gui 像这样运行它时,它看起来都很糟糕。特别是如果我每秒调用它很多次。
  • @blez:如果你在一秒钟内调用了很多次,那么你几乎肯定会使用线程池。

标签: c# .net multithreading c#-2.0


【解决方案1】:

一方面,声明自己的代表似乎没有意义。为什么不只是:

void Async(ThreadStart t) {
    Thread thread = new Thread(t);
    thread.IsBackground = true;
    thread.Start();
}

?就我个人而言,我看不到自己想要经常这样做(并且没有方法来了解任务的进展情况)以保证单独的方法。如果您使用的是 .NET 4,您应该查看任务并行库,它仍然允许您启动异步任务 - 但以一种功能更全面的方式。 (编辑:好的,所以你不能在 .NET 2 中使用它——不过未来值得牢记。)

您可能还想考虑在委托上使用BeginInvoke 方法,它允许您在线程池中轻松启动它们 - 传递参数:

Action<string, int> action = (name, age) => { ... };

IAsyncResult result = action.BeginInvoke("Jon", 35, null);
// Now you can use result if you want...

编辑:您现在已经说过您将每秒执行几次。假设这是一个短期任务,您几乎可以肯定应该为此使用线程池。除了上面的例子,你还可以使用ThreadPool.QueueUserWorkItem 向线程池添加一个任务。这将比每次有任务时创建一个新线程更有效(通过线程重用)。

【讨论】:

  • 我将它用于繁重的任务和许多小任务(例如 100 次呼叫/秒)。使用线程池总是更好的选择吗?没用过Action,是不是第三种调用异步代码的方式?
  • @blez: Action&lt;,&gt; 只是一个示例委托类型(实际上来自 .NET 3.5,但它只是一个委托类型 - 显然,您可以声明自己的委托类型)。 所有委托都有BeginInvoke方法。您绝对应该将线程池用于短期任务。运行时间较长的可以明智地使用单独的线程。
【解决方案2】:

因为你已经有一个委托

private delegate void MyDelegate();

你可以这样做

new MyDelegate(delegate
{
    // code
}).BeginInvoke(null, null);

它会使用线程池线程,这样您就不会因为过多的线程而导致运行时不堪重负。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    相关资源
    最近更新 更多