我应该如何与每个 Task.Factory.StartNew() 方法共享一个大的只读列表

本文关键字:一个 只读 列表 共享 Task Factory StartNew 方法 我应该 | 更新日期: 2023-09-27 18:35:06

考虑到我有一个名为Terms的自定义类,该类包含许多字符串属性。然后我创建一个相当大的(比如 50,000)List<Terms>对象。此List<Terms>只需要从中读取,但需要由多个Task.Factory.StartNew实例读取(实例数可能从 1 到 100 不等)。

如何最好地将该列表传递到长时间运行的任务中?内存不是太大的问题,因为这是一个自定义应用程序,用于具有大量内存的特定服务器上的特定用途。我应该引用它还是应该将其作为普通参数传递给执行工作的方法?

我应该如何与每个 Task.Factory.StartNew() 方法共享一个大的只读列表<T>

由于您正在传递引用,因此如何传递它并不重要,它不会复制列表本身。正如 Ket Smith 所说,我会将其作为参数传递给您正在执行的方法。

问题是List<T>不完全是线程安全的。多线程读取是安全的,但写入可能会导致一些问题:

对 List 执行多个读取操作是安全的,但如果在读取集合时对其进行修改,则可能会出现问题。若要确保线程安全,请在读取或写入操作期间锁定集合

List<T>

您说您的列表是只读的,因此这可能不是问题,但是单个不可预测的更改可能会导致意外行为,因此容易出错。

我建议使用本质上是线程安全的ImmutableList<T>因为它是不可变的。

只要你不尝试将它复制到每个单独的任务中,它应该不会有太大区别:更多的是编码风格的问题。每个任务仍将在内存中使用相同的列表:只是对同一基础列表的不同引用。

也就是说,纯粹是编码风格和可维护性的问题,我可能会尝试将其作为参数传递给您在Task.Factory.StartNew()中执行的任何方法(或者更好的是,Task.Run() - 见这里)。这样,您已经清楚地调用了任务的依赖项,如果您决定需要从其他地方获取列表,则必须更清楚地更改内容。(但是你可能会在我自己的代码中找到20个我没有遵循该规则的地方:有时我会选择现在对我来说更容易的东西,而不是六个月后对我来说可能更容易的地方。