我有一个配置 xml,它正在由我的 .Net 3.5 Windows 应用程序中的批处理模块使用。 xml 中的每个节点都映射到一个 .Net 类。每个类都会进行数学计算、数据库调用等处理。
批处理模块加载 xml,识别与每个节点关联的类,然后对其进行处理。
现在,我们有以下要求:
1.假设有 3 个类[xml 中的 3 个节点]...A、B 和 C。 A 类可以依赖于 B 类......即。我们需要在处理 A 类之前执行 B 类。C 类处理应该在单独的线程上完成。
2.如果一个线程正在运行,那么我们应该能够在处理过程中取消该线程。
我们需要使用.net多线程来实现整个模块。
我的问题是: 1.是否可以实现上述要求#1?如果可以,如何实现?
2.考虑到这些要求,.Net 3.5是一个好主意还是.Net 4.0会是更好的选择?想知道优点和缺点。
感谢您的阅读。
最佳答案
您最好使用 Task Parallel Library (TPL) in .NET 4.0 。它将为您提供许多很好的功能,用于抽象在线程池中创建线程的实际业务。您可以使用 parallel tasks pattern为 XML 中定义的每个作业创建一个任务,TPL 将处理这些任务的调度,而不管硬件如何。换句话说,如果您转移到具有更多内核的计算机,TPL 将调度更多线程。
1) TPL 支持 continuation tasks 的概念。您可以使用它们来强制执行任务排序,并将一个任务或将来任务的结果从先行项传递到延续项。这是futures pattern .
// The antecedent task. Can also be created with Task.Factory.StartNew.
Task<DayOfWeek> taskA = new Task<DayOfWeek>(() => DateTime.Today.DayOfWeek);
// The continuation. Its delegate takes the antecedent task
// as an argument and can return a different type.
Task<string> continuation = taskA.ContinueWith((antecedent) =>
{
return String.Format("Today is {0}.",
antecedent.Result);
});
// Start the antecedent.
taskA.Start();
// Use the contuation's result.
Console.WriteLine(continuation.Result);
2) TPL 支持线程取消,但它是协作取消。换句话说,任务中运行的代码必须定期检查它是否已被取消并彻底关闭。 TPL有好support for cancellation 。请注意,如果您直接使用线程,您会遇到相同的限制。 Thread.Abort 在几乎所有情况下都不是一个可行的解决方案。
当您查看时,您可能想查看 dependency injection container就像 Unity 从 XML 配置生成配置对象一样。
评论答案(如下)
吉米:我不确定我是否理解霍尔塔伏特的评论。事实是,只有在完成的工作量很大时,使用并行性才会有返回,否则您的程序可能会花费更多的时间来管理并行性,而不是做有用的工作。实际数据集不必很大,但工作量必须很大。
例如,如果您的输入是大数字,并且我们检查它们是否是素数,那么数据集将非常小,但并行性仍然会得到返回,因为每个数字或数字 block 的计算成本很高。相反,您可能有一个非常大的数字数据集,您正在寻找均匀性。这将需要非常大的数据集,但计算仍然非常便宜,并且并行实现可能仍然不会更有效。
典型的示例是使用 Parallel.For
而不是 for
来迭代数据集(大或小),但仅执行简单的数字运算,例如加法。在这种情况下,创建并行任务以及调度和管理它们的开销超过了利用多核的预期性能改进。
关于c# - .Net 中的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5718136/