【问题标题】:Understanding System.Threading.Tasks behavior了解 System.Threading.Tasks 行为
【发布时间】:2013-05-04 19:29:25
【问题描述】:

我目前正在尝试通过使用 Tasks 来利用 .Net 4.0 中的并行线程来进行一些性能优化。

我已经创建了三个方法来返回一些对象的集合或只是一个对象。 我们称它们为 MethodA、MethodB 和 MethodC。

在 MethodB 内部,我有一个长时间运行的延迟 - 大约 5-7 秒。

var person = new Person();

person.A = Task.Factory.StartNew(() => Mystatic.MethodA()).Result;
person.B = Task.Factory.StartNew(() => Mystatic.MethodB()).Result;
person.C = Task.Factory.StartNew(() => Mystatic.MethodC()).Result;

现在我希望在 person.B 之前设置/填充 person.A 和 person.C 属性,但我很难测试/调试它来验证我的假设。

我已经在所有三个属性上添加了一个并行监视,但是调试并不能说明我的问题。

如果我正在填充一个主对象,这也是我优化对方法的多个调用的正确方法吗?

在我的例子中,我有 5-7 种不同的方法来收集数据,我想让它们并行,因为其中一些相对耗时。

【问题讨论】:

  • 旁注:写Task.Factory.StartNew.
  • 很好 - 这更简单:)

标签: c# multithreading c#-4.0 task


【解决方案1】:

原则上依赖时间是错误的,因为时间永远无法保证,尤其是在实际条件下。如果您需要确保任务已完成,您应该对任务应用适当的等待。或使用 C# 5.0 async-await 或延续。

简而言之,不要巧合地编程。通过构造使您的程序正确。

【讨论】:

  • +1。作为旁注,如果对象在创建后需要(冗长的)初始化,我将包含一个 public static Task<Person> CreateAsync() 方法并(可能)将构造函数设为私有。但我离题了:)
  • 这是正确答案。但是,如果你真的只是想使用调试器来测试你的怀疑(也是一个有问题的做法),你可以在每个属性设置器中执行一个简单的 Debug.Write,或者可能只是在每个设置器中设置一个断点。跨度>
  • 通过调试,我的意思是对每个属性进行监视,并在范围的末端设置一个断点,并密切关注监视。我会尝试使用 await / async 进行试验,但这不在我目前使用的框架版本中:(
【解决方案2】:

你的假设是错误的。 Task 的 Result 属性将有效地等待任务完成 - 因此, A、 B 、 C 将按该顺序分配。此外,这会破坏创建异步任务的目的。

一种方法是您可以在所有三个任务上使用 Task.WaitAll,然后将每个任务的结果分配给 A、B、C

如果您有 VS2012,您也可以使用 async/await - 您仍然可以使用 http://nuget.org/packages/Microsoft.Bcl.Async/ 定位 .NET 4.0

但是,如果您这样做,async/await 将不会并行启动 3 个任务:

person.A = await Task.Run(() => Mystatic.MethodA());
person.B = await Task.Run(() => Mystatic.MethodB());
person.C = await Task.Run(() => Mystatic.MethodC());

它仍然是顺序的 - 如果你想在某种程度上并行执行,你可以这样做:

Task tA = Task.Run(() => Mystatic.MethodA());
Task tB = Task.Run(() => Mystatic.MethodB());
Task tC = Task.Run(() => Mystatic.MethodC());

person.A = await tA;
person.B = await tB;
person.C = await tC;   

【讨论】:

  • 是的,我得到了一位同事的解释。我担心的是,各个线程是并行工作的,而不是顺序工作的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-28
  • 2019-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多