2013-06-01 58 views
0

我遇到了解Mutex類以及如何在WP8應用程序中正確使用它的問題。我試圖做的是隻允許一個ScheduledAgent或應用程序一次讀/寫文件到存儲。我已經嘗試過這種方式,沒有運氣。任何幫助,將不勝感激。WP8 Mutex - 資源鎖定

ScheduledAgent代碼:

下面代碼中的錯誤,當我調用ReleaseMutex()。當我創建Mutex對象時,此問題已修復:new Mutex(true,「FlightPathData」)。但我永遠不能得到WaitOne的鎖和掛起()

錯誤

對象同步方法從代碼不同步塊調用。

代碼

readonly Mutex mutex = new Mutex(false, "FlightPathData"); 

protected async override void OnInvoke(ScheduledTask task) 
{ 
     List<METAR> savedMetars = null; 
     var facility = ....; 

     bool mutexAcquired = mutex.WaitOne(); 
     try 
     { 
      if (mutexAcquired) 
      { 
       savedMetars = await Data.LoadMetarsAsync(facility.Identifier); 
       //Thread.Sleep(15000); 
      } 
     } 
     finally 
     { 
      if (mutexAcquired) 
      { 
       mutex.ReleaseMutex(); 
      } 
     } 

     NotifyComplete(); 
} 

ViewModelCode(工程罰款,直到ScheduledAgent ReleaseMutex()失敗)

static readonly Mutex mutex = new Mutex(true, "FlightPathData"); 
... 
mutex.WaitOne(); 
var savedMetars = await Data.LoadMetarsAsync(this.Facility.Identifier); 
mutex.ReleaseMutex(); 
+0

看起來這一行:savedMetars = await Data.LoadMetarsAsync(facility.Identifier);導致任務進入另一個線程,因爲它是異步的,當它嘗試釋放它不能的Mutex時。我評論說,代碼和一切工作,因爲它應該...非常奇怪。 – Clarke76

+0

@Stehen:你能詳細解釋一下「你不能在異步代碼中使用互斥鎖嗎?」嗎?在我的UWP應用程序中,我需要同步前臺應用程序及其後臺任務(生活在不同的進程中)之間的資源訪問(例如存儲文件)。在我的[測試](http://stackoverflow.com/questions/35843812/how-to-synchronize-resource-access-between-uwp-app-and-its-background-tasks)互斥似乎工作正常(我知道不是證明)。 –

回答

1

不能使用線程仿射鎖與async代碼。這是因爲await可能導致方法返回(同時持有互斥鎖),然後另一個線程可以繼續執行方法並嘗試釋放它不擁有的互斥鎖。如果這是令人困惑的,我有一個async intro blog post,你可能會發現有幫助。

因此,您不能使用Mutex或其他線程仿射鎖,如lock。但是,您可以使用SemaphoreSlim。在您的async方法中,您將使用await WaitAsync而不是Wait

+0

我其實剛讀完一篇關於async/await的文章,並且即將發佈你剛纔陳述的內容。我不知道SemaphoreSlim,當然會做一些閱讀。話雖如此,我最終創建了與IsolatedStorage同步寫入的其他方法,確實解決了問題。欣賞帖子和鏈接! – Clarke76

+0

@Stehen:您能否詳細解釋一下「您不能在異步代碼中使用互斥鎖」?在我的UWP應用程序中,我需要同步前臺應用程序及其後臺任務(生活在不同的進程中)之間的資源訪問(例如存儲文件)。在我的測試中,互斥似乎工作正常(我知道這不是證明)。 –

+0

@PeterMeinl:互斥體是線程仿射的,所以它們不適用於異步代碼。 http://stackoverflow.com/questions/7612602/why-cant-i-use-the-await-operator-within-the-body-of-a-lock-statement –