2011-08-29 51 views
1

如何設置Unity,以便類可以異步初始化而不阻止其他模塊的加載(僅阻止顯式需要異步類型實例的其他類型)?我正在考慮的類是參考數據緩存,它從數據庫中提取常用數據的快照,並且我需要在讓其他模塊訪問它之前完成預先緩存(如果請求在我的類I中被阻止將迅速阻止主線程並阻止所有其他模塊進行初始化)。這已成爲我有多個這樣的引用數據類如何爲類型/模塊的異步初始化配置Unity

舉例來說更爲重要,說我有一個這樣的類:

public class ProductCache{ 

    public ProductCache(){} 

    public Initialize(){ 
     // a very slow DB call to fetch frequently used products 
     Thread.Sleep(30*1000); 
    } 

    public Product FindProduct(string productDescription){ 
     /* check cache, if not there try the db */ 
    } 
} 

如果我調用初始化從構造我會阻塞調用它的線程(來自Unity)30秒鐘,阻止我同時創建其他(類似)類。如果我簡單地將任務放在線程池上,Unity最終會達到需要我的產品緩存的另一個類正在執行其初始化代碼的地步,然後訪問尚未完全初始化的數據結構(在這種情況下,會導致在高速緩存未命中和數據庫的調用來獲取特定的產品,並有可能在30秒內很多這樣的請求)

感謝 奧斯卡

+0

你能提供一些代碼,那就是你正在初始化的類的結構嗎? – onof

+0

增加了一個小例子 – Oskar

回答

1

你需要做的正在運行的任務列表,請執行它們並行,並使用Task.WaitAll()等待它們完成後再繼續。

在.NET 4中,這應該工作和錯誤處理變得容易:

public void InitializeAll() 
{ 
    List<Task> initTasks = new List<Task>(); 

    ProductCache productCache = new ProductCache(); 
    SomeOtherCache someOtherCache = new SomeOtherCache(); 

    initTasks.Add(Task.Factory.StartNew(() => productCache.Initialize())); 
    initTasks.Add(Task.Factory.StartNew(() => someOtherCache.Initialize())); 

    try 
    { 
     Task.WaitAll(initTasks.ToArray()); 
    } 
    catch (AggregateException ex) 
    { 
     Console.WriteLine("Oh dear!"); 
    } 
} 

在老派的.Net,試試這個。我假設你爲每個可初始化的對象使用一個接口,並且我省去了錯誤處理:

public void InitializeAll(IEnumerable<IInitializable> initializeUs) 
{ 
    List<WaitHandle> handles = new List<WaitHandle>(); 

    foreach(IInitializable init in initializeUs) 
    { 
     // Make a copy of the reference in the local scope 
     IInitializable temp = init; 

     ManualResetEvent done = new ManualResetEvent(false); 
     handles.Add(done); 

     ThreadPool.QueueUserWorkItem(delegate 
     { 
      try 
      { 
       temp.Initialize(); 
      } 
      finally 
      { 
       done.Set(); 
      } 
     }); 
    } 

    // Wait for all the handles to be set 
    WaitHandle.WaitAll(handles.ToArray()); 
} 
+0

是的,這解決了這個問題。我想我希望Unity中的某些東西(比如說一個標記組件的屬性)會觸發這種行爲。它也能夠使用模塊依賴性來確保正確解釋任何依賴關係 – Oskar

+0

我明白你的意思了。您可以在模塊初始化期間使用上面的代碼來並行註冊類型的實例,這應該處理依賴注入。不過,您可能會遇到不同類型之間依賴關係的問題。 –