>我最近继承了一个系统,它使用非常基本的方法来处理工作项目,基本上,它一个接一个地处理它们。老实说,直到最近,这还很有效。但是,我们希望为另一种类型的工作项目实现类似的过程,我一直在研究任务并行库,并认为这将符合要求。但是,我对线程安全有一些担忧,老实说,这是我缺乏知识的领域,所以我在这里只问我的第二个问题,希望有人能给我一些好的观点,因为我还没有找到一个明确的是或否答案。
所以我们有我们的"工作项"类
public class WorkItem
{
public int Id {get; set;}
public string data { get; set;}
}
将生成一个List<WorkItem>
,然后使用 Parallel.Foreach
循环处理这些。
Parallel.Foreach
将调用私有方法,而私有方法又会调用另一个程序集中的静态方法;
//Windows service that will run the Parallel.Foreach
private int MainMethod(WorkItem item)
{
item.Data = Processor.ProcessWorkItemDataProcess1(item.data);
item.Data = Processor.ProcessWorkItemDataProcess2(item.data);
SendToWorkFlow(item);
}
public static class Processor
{
public static string ProcessWorkItemDataProcess1(string data)
{
//Process it here
return string
}
public static string ProcessWorkItemDataProcess2(string data)
{
//Process it here
return string
}
}
等等。所有这些方法都具有在各个不同阶段处理工作项实例的逻辑。完成后,MainMethod
会将处理后的工作项发送到工作流系统。
我们将分批处理这些,最多 30 个,以免其他系统过载。我担心的基本上是 30 个WorkItem
实例访问相同静态方法可能会导致一些数据完整性问题。例如,ProcessWorkItemDataProcess2
使用 WorkItem1.Data
调用,随后使用 WorkItem2.Data
调用,并且不知何故在应该WorkItem1.Data
时返回WorkItem2.Data
所有静态方法都是自包含的,只要它们定义了逻辑,并且(理论上(只会使用调用它的WorkItem
。没有数据库访问、文件访问等方法。
所以,希望这能解释我在做什么。我应该有任何顾虑吗?如果是这样,为每个工作项创建 Processor
类的实例是否可以解决任何潜在问题?
提前致谢
您描述的场景听起来没有任何明显的线程问题。 你担心静态方法在两个不同的线程上被调用并混淆数据是没有根据的,除非你编写代码来混淆事情。 ;>
由于这些方法是静态的,因此它们没有任何共享对象实例需要担心。 很好。 您已将工作隔离到独立的工作项中。 很好。
您需要检查以确保没有任何静态方法访问任何全局状态,如静态变量或属性,或从文件读取(多个工作项的相同文件名(。 阅读全球状态不是一个问题,写作是会给作品带来麻烦的东西。
还应查看代码,以了解如何将数据分配给工作项,以及处理工作项的任何代码是否修改了工作项数据。 如果方法将工作项视为严格只读,那就太好了。 如果方法将更改写回工作项的字段或属性,则需要仔细检查工作项中的数据是否未与任何其他工作项共享。 如果构造工作项实例的代码将缓存值分配给多个工作项的属性,并且静态方法修改该值的属性,则会出现线程冲突。 如果工作项构造始终构造分配给工作项属性的值的新实例,则这应该不是问题。
简而言之,如果您有多个线程访问共享状态,并且至少有一个线程正在写入,那么您需要担心线程安全性。如果不是,那么你就是金子。