C# 了解System.Threading.Tasks行为

C# 了解System.Threading.Tasks行为,c#,multithreading,c#-4.0,task,C#,Multithreading,C# 4.0,Task,我目前正试图通过使用任务来利用.NET4.0中的并行线程来进行一些性能优化 我创建了三个方法,它们返回一些对象的集合,或者只返回一个对象。 我们把它们叫做MethodA、MethodB和MethodC 在MethodB内部,我有一个长时间运行的延迟-大约5-7秒 var person = new Person(); person.A = Task.Factory.StartNew(() => Mystatic.MethodA()).Result; person.B = Task.Fact

我目前正试图通过使用任务来利用.NET4.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.A和person.C属性在person.B之前设置/填充,但是我很难测试/调试它来验证我的假设

我在所有三个属性上都添加了一个并行手表,但通过调试并不能为我澄清问题

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


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

依赖计时原则上是错误的,因为计时永远无法保证,特别是在实际的word条件下。如果需要确保任务已完成,则应应用适当的等待任务。或者使用C5.0异步等待,或者continuations


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

依赖计时原则上是错误的,因为计时永远无法保证,特别是在实际的word条件下。如果需要确保任务已完成,则应应用适当的等待任务。或者使用C5.0异步等待,或者continuations


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

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

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

如果您有VS2012,还可以使用async/await,您仍然可以使用

但是,请理解,如果执行以下操作,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;   

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

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

如果您有VS2012,还可以使用async/await,您仍然可以使用

但是,请理解,如果执行以下操作,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;   

侧注:只需编写Task.Factory.StartNew.Nice-简单得多:侧注:只需编写Task.Factory.StartNew.Nice-简单得多:+1。作为旁注,如果对象在创建后需要一个长时间的初始化,我将包括一个公共静态任务CreateAsync方法,并可能将构造函数设为私有。但我离题了:这是正确的答案。但是,如果您真的只是想使用调试器来测试您的怀疑,这也是一种有问题的做法,您可以只进行简单的调试。在每个属性设置器中编写,或者可能只是在每个设置器中设置一个断点。通过调试,我的意思是对每个属性进行监视,并在作用域的末尾设置一个断点,并一直盯着手表。我会尝试使用wait/async进行实验,但这不在我当前使用的框架版本中:+1。作为旁注,如果对象在创建后需要一个长时间的初始化,我将包括一个公共静态任务CreateAsync方法,并可能将构造函数设为私有。但我离题了:这是正确的答案。但是,如果您真的只是想使用调试器来测试您的怀疑,这也是一种有问题的做法,您可以只进行简单的调试。在每个属性设置器中编写,或者可能只是在每个设置器中设置一个断点。通过调试,我的意思是对每个属性进行监视,并在作用域的末尾设置一个断点,并一直盯着手表。我会尝试使用wait/async进行实验,但这不在我目前使用的框架版本中:是的,我得到了一位同事的解释。我担心的是,单个线程是并行工作的,而不是顺序工作的。是的,我的同事解释了这一部分。我担心的是,单个线程是并行工作的,而不是顺序工作的。