2017-02-13 37 views
0

我有MVC API控制器。 此控制器中的一種方法非常重要。 這意味着所有其他API方法必須等待util這個方法完成。API方法必須等到重要方法完成

我的基本想法是阻止構造函數中的線程。 但我不確定這是否如此聰明?

public class TestApi : Controller 
{ 
    private static bool wait = false; 
    public TestApi() 
    { 
     // wait if critical method is working. 
     while (wait) 
     { 
      System.Threading.Thread.Sleep(100); 
     } 
    } 

    [HttpPost] 
    public void PostCriticalMethod() 
    { 
     try 
     { 
      wait = true; 
      // do critical work 
     } 
     finally 
     { 
      wait = false; 
     } 
    } 
    // Many non critical API methods... 
} 

解決方法二:

public class TestApi : Controller 
    { 
     private static bool wait = false; 
     private static AutoResetEvent waitHandle = new AutoResetEvent(false); 
     public TestApi() 
     { 
      // wait if critical method is working. 
      if (wait) waitHandle.WaitOne(); 
     } 

     [HttpPost] 
     public void PostCriticalMethod() 
     { 
      try 
      { 
      wait = true; 
      // do critical work 
      } 
      finally { 
      waitHandle.Set(); 
      wait = false; 
      } 
     }   
     // Many non critical API methods... 
    } 
+5

如果你在api中需要這個,那麼在我看來它需要重新考慮這個設計。 Api的不應該像這樣工作。你爲什麼需要這個?如果你告訴你的挑戰而不是你的解決方案,也許我們可以做得更好。 –

+0

我有API,其中任務是恢復數據庫。其他API方法必須等到數據庫恢復。 – Raskolnikov

+0

這種方法的缺點是,當第一個API請求被創建(在該控制器上的請求)時,數據庫恢復將開始,我認爲這太遲了。請求API的第一個客戶端肯定會被阻止,並且其他呼叫者也會被阻止(只要恢復過程需要)。更好的方法是在WEB啓動期間運行這個「恢復任務」 – tomassino

回答

0

我的解決方案(這是異步的版本,但非異步更簡單):

在基類(通用於所有控制器),我想補充方法BlockOtherRequestsBeforeExecute

 private static readonly SemaphoreSlim semaphoreInit = new SemaphoreSlim(1, 1); 

     protected async Task BlockOtherRequestsBeforeExecute(Func<Task> criticalAction) 
     { 
      await semaphoreInit.WaitAsync(); 
      try 
      { 
       await criticalAction(); 
      } 
      finally 
      { 
       semaphoreInit.Release(); 
      } 
     } 

然後我可以用安全的方式調用方法,如果我需要的話:

await BlockOtherRequestsBeforeExecute(async() => await RestoreDatabase()); 

重要的部分是,semaphoreInit必須在所有關鍵的地方使用。 這可以在基類的構造函數中完成,然後所有API-s都會被阻塞,直到關鍵操作未完成。