我有一個簡單的Employee類如下我可以設計任何無鎖解決方案,此方案
public class Employee
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
}
然後我有做的方法,這些員工被稱爲ProcessThisEmployee的併發處理的ProcessEmployees類。在這種方法中,我必須調用第三方庫方法。迄今爲止它的一切都很簡單問題出現在用戶選擇取消該操作時,我需要對尚未完成處理的任何ThirdPartyLibrary類實例進行一些清理。注意我沒有對ThirdPartyLibrary類的任何控制權,並且沒有任何取消現有任務的機制。它確實提供了一個Clean方法,我可以調用SomeAPI調用尚未完成的任何實例。因此,我維護着所有實例的本地列表。當用戶選擇取消操作時,我調用我的類的CleaupIfUserCancelOperation方法,該方法是將此第三方庫實例的Clean方法放在我的本地列表中。以下是我的代碼。
class ProcessEmployees
{
private List<Employee> _Employees;
List<ThirdPartyLibrary> libraries = new List<ThirdPartyLibrary>();
private object sync = new object();
public ProcessEmployees()
{
_Employees = new List<Employee>()
{
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();
}
}
我必須在這裏鎖定庫實例兩次,這當然是性能打擊。在這種情況下可以使用任何輕量級(無鎖)機制嗎?我對併發集合不太瞭解,不知道這些可能在這種情況下有什麼用處?
我已經想出了另一種使用您的建議的方法,但我不確定這是否是最佳方法。我已經發布了單獨的問題http://stackoverflow.com/questions/27883091/is-it-a-reasonable-approach-for-lock-free-design-for-this-scenario –