2015-01-10 121 views
-2

我有一個簡單的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(); 
    } 
} 

我必須在這裏鎖定庫實例兩次,這當然是性能打擊。在這種情況下可以使用任何輕量級(無鎖)機制嗎?我對併發集合不太瞭解,不知道這些可能在這種情況下有什麼用處?

回答

2

這兩個鎖調用的性能影響可能比您正在執行的其他操作更少。假設他們可以使用ConcurrentDictionary來添加和刪除實例(不應該使用List,因爲現在你在併發庫的數量上會有二次性能開銷)。

這可能會更好地使每個異步方法取消自己並清理自己的東西。通過他們CancellationToken。使用Register註冊清理庫的回調。這裏真的不需要全球的州/集合。

+0

我已經想出了另一種使用您的建議的方法,但我不確定這是否是最佳方法。我已經發布了單獨的問題http://stackoverflow.com/questions/27883091/is-it-a-reasonable-approach-for-lock-free-design-for-this-scenario –