我可以为此方案设计任何无锁解决方案

我有一个简单的Employee类如下

public class Employee { public int ID { get; set; } public string LastName { get; set; } public string FirstName { get; set; } } 

然后我有一个ProcessEmployees类,它在名为ProcessThisEmployee的方法中对这些员工进行并发处理。 在这种方法中,我必须调用第三方库方法。 到目前为止一切都很简单。 问题是用户在进行操作时选择取消此操作的某个时候,我需要对尚未完成处理的任何ThirdPartyLibrary类实例进行一些清理。 注意我对ThirdPartyLibrary类没有任何控制,并且它没有任何取消现有任务的机制。 它提供了一个Clean方法,我可以在任何调用SomeAPI尚未完成的实例上调用它。 因此,我正在维护所有实例的本地列表。 当用户选择取消操作时,我调用我的类的CleaupIfUserCancelOperation方法,即清理我本地列表中第三方库实例的方法。 以下是我的代码。

 class ProcessEmployees { private List _Employees; List libraries = new List(); private object sync = new object(); public ProcessEmployees() { _Employees = new List() { new Employee() { ID = 1, FirstName = "John", LastName = "Doe" }, new Employee() { ID = 2, FirstName = "Peter", LastName = "Saul" }, new Employee() { ID = 3, FirstName = "Mike", LastName = "Sue" }, new Employee() { ID = 4, FirstName = "Catherina", LastName = "Desoza" }, new Employee() { ID = 5, FirstName = "Paul", LastName = "Smith" } }; } public void StartProcessing() { Task[] tasks = this._Employees.AsParallel().Select(x => this.ProcessThisEmployee(x)).ToArray(); Task.WaitAll(tasks); // other stuff } private async Task ProcessThisEmployee(Employee x) { ThirdPartyLibrary library = new ThirdPartyLibrary(); lock (sync) { libraries.Add(library); } await Task.Factory.StartNew(() => library.SomeAPI(x) ); lock (sync) { libraries.Remove(library); } } private void CleaupIfUserCancelOperation() { foreach (ThirdPartyLibrary library in libraries) library.Clean(); } } 

我必须在这里两次锁定库实例,这当然是性能损失。 在这种情况下可以使用任何轻量级(无锁)机制吗? 我不太了解并发收集,想知道这些在这种情况下是否有用?

两个锁定调用很可能比您正在执行的其他操作具有更少的性能影响。 假设它们可以使用ConcurrentDictionary来添加和删除实例(您不应该使用List,因为现在您在并发库的数量上有二次性能开销)。

最好让每个异步方法取消自身并清理自己的东西。 将它们传递给CancellationToken 。 使用Register注册清理库的回调。 这里真的没有必要使用全球州/馆藏。