考虑我有一个名为的自定义类Terms
,并且该类包含许多字符串属性。然后我创建了一个相当大(比如 50,000)的List<Terms>
对象。这只List<Terms>
需要读取,但需要由多个实例读取Task.Factory.StartNew
(实例的数量可能从 1 到 100 不等)。
我如何最好地将该列表传递给长期运行的任务?内存不是太大的问题,因为这是在具有大量内存的特定服务器上的特定用途的自定义应用程序。我应该引用它还是应该将它作为正常参数传递给执行工作的方法?
考虑我有一个名为的自定义类Terms
,并且该类包含许多字符串属性。然后我创建了一个相当大(比如 50,000)的List<Terms>
对象。这只List<Terms>
需要读取,但需要由多个实例读取Task.Factory.StartNew
(实例的数量可能从 1 到 100 不等)。
我如何最好地将该列表传递给长期运行的任务?内存不是太大的问题,因为这是在具有大量内存的特定服务器上的特定用途的自定义应用程序。我应该引用它还是应该将它作为正常参数传递给执行工作的方法?
由于您正在传递一个引用,因此您如何传递它并不重要,它不会复制列表本身。正如 Ket Smith 所说,我会将它作为参数传递给您正在执行的方法。
问题List<T>
并不完全是线程安全的。多线程读取是安全的,但写入可能会导致一些问题:
对 List 执行多个读取操作是安全的,但如果在读取集合时对其进行了修改,则可能会出现问题。为确保线程安全,请在读取或写入操作期间锁定集合。
您说您的列表是只读的,因此这可能不是问题,但是单个不可预测的更改可能会导致意外行为,因此很容易出错。
我建议使用ImmutableList<T>
它本质上是线程安全的,因为它是不可变的。
只要您不尝试将其复制到每个单独的任务中,它就不会产生太大影响:更多的是编码风格问题。每个任务仍将使用内存中的相同列表:只是对相同底层列表的不同引用。
也就是说,纯粹作为编码风格和可维护性的问题,我可能会尝试将它作为参数传递给您正在执行的任何方法Task.Factory.StartNew()
(或者更好,Task.Run()
请参见此处)。这样,您已经清楚地调用了任务的依赖关系,并且如果您决定需要从其他地方获取列表,那么您需要更改的内容就更清楚了。(但你可能会在我自己的代码中找到 20 个地方我没有遵循这条规则:有时我会选择现在对我来说更容易的东西,而不是六个月后对我来说可能更容易的东西。)