【问题标题】:Task<T> vs Asynchronous delegates in c#?Task<T> vs C#中的异步委托?
【发布时间】:2012-12-04 07:37:39
【问题描述】:

我有这个简单的方法:

static int Work (string s) { return s.Length; }

我可以运行它:

Task<string> task = Task.Factory.StartNew<int> (() => Work ("lalala") );
...
int result = task.Result;

或者用这个:

Func<string, int> method = Work;
IAsyncResult myIasync= method.BeginInvoke ("lalala", null, null);
...
int result = method.EndInvoke (myIasync);
  • 它们都使用线程池线程。
  • 两者都等待执行完成(读取值时)
  • 两者都向调用者重新抛出任何异常。

我应该什么时候使用每个?

【问题讨论】:

  • 我认为任务更好,因为它更新,但我几乎不相信这个小代码会有任何不同。

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


【解决方案1】:

第二种形式,使用IAsyncResult,明显更老,而且功能更弱。 Task&lt;T&gt; 是在 .NET 4 中引入的,现在是表示异步操作的首选方式。它使用起来要简单得多,尤其是在支持“异步函数”的 C# 5 中,您可以在其中以非阻塞方式等待任务(或其他异步操作)。

使用Task 而不是调用BeginInvoke 可能不会对操作本身的执行方式产生太大影响(尽管它在调度等方面为您提供了更多选择),但从角度来看却有很大不同想要“观察”操作、使用结果、等待多个任务、处理故障等的代码。

如果您可以使用 C# 5(使用 .NET 4.5,或者使用 .NET 4 加上异步目标包),那么在管理异步操作时,您的工作将变得更加轻松。这是前进的道路:)

【讨论】:

  • 谢谢。假设任务需要很长时间才能执行。它是否会绑定一个线程池线程直到它完成(所以现在线程池有 [n-1] 个线程)?或者工作被委派给非线程池线程,只有在完成后,它才会回到线程池线程......?
  • @AutoExec.Bat:如果你使用Task,你可以告诉它这是一个长时间运行的任务,在这种情况下它会使用一个非线程池线程。目前尚不清楚“它回到线程池线程”是什么意思。 what 会回到线程池线程吗?
  • 必须完成一项工作。这是一项长期的工作。该作业可以使用 threadpool-thread 执行,它可以转移到 non-threadpool 线程(所以现在线程 back 到池 - 为其他请求提供服务器),当作业完成时(在非线程池线程中) - 它发出信号:“嘿,我完成了作业” 并且控制返回一个线程池线程。 (这个想法是为了避免线程池线程被浪费)。所以我的问题是:Task vs IAsync 如何以这种方式工作......(实际工作是否被线程池或非线程池线程疯狂?)
  • 附注现在我已经看到(正如你提到的)该任务具有 LongRunning 标志,它完全可以做到这一点。所以剩下的问题是关于异步委托的。谢谢:-)
  • @AutoExec.Bat:“控制回到线程池线程”——什么控制?我认为您需要退后一步,想想每个线程实际上在做什么。我相信,在委托上使用 BeginInvoke 总是使用线程池线程。
【解决方案2】:

Task 更优雅,并且是最近引入的(.Net 4),所以如果它满足您的需求,我会选择它。

【讨论】:

    猜你喜欢
    • 2012-05-29
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 2019-06-23
    • 2023-03-26
    • 1970-01-01
    • 2014-06-11
    相关资源
    最近更新 更多