2013-08-03 64 views
2

我試圖在應用程序關閉/停用時保存應用程序數據。 在WP8中我使用了StorageFile,它只支持Async方法。應用程序生命週期事件(例如Application_Closing)上的異步方法

問題是(正如我在閱讀this article時懷疑並確認的),簡單地說,操作系統生命週期事件和異步方法不能很好地混合在一起。所以,這不工作(即使沒有異步/等待)

private async void Application_Deactivated(object sender, DeactivatedEventArgs e) 
{ 
    var dataSvc = SimpleIoc.Default.GetInstance<ICachedDataService>(); 
    await dataSvc.StoreCachedDataAsync(); 
} 

文章建議2解決辦法,沒有一個似乎理想:

  1. 使用不同的API,例如IsolatedStorage而不是StorageFolder/File,它支持同步操作。
  2. 另存爲你去與保存到底

我和(2)的問題,它仍然不能保證,這將有時間來保存,即使我儘快啓動它儘可能。 (1)的問題是...... beh ...我使用ServiceLocator/IoC模式(我永遠不會記得哪個模式是什麼),所以這迫使我在界面中引入同步操作例如,ICachedDataProvider

有沒有其他方法?是否可以將Async方法轉換爲同步方法以增加代碼重用?

回答

2

是否可以將異步方法轉換爲同步方法以增加代碼重用?

不幸的是,沒有。你可以採取多種方法來包裝這些方法,但它們都不是萬無一失的。 This blog entry描述了各種方法。在你的情況下,我會建議卸載到另一個線程;這是最簡單的工作,但只有在ICachedDataProvider是線程安全的情況下才有效。

1

我發現似乎工作,但我會讓這個問題坐下來等待反饋或其他解決方案。

我修改Application_Closing和Application_Deactivated以下(基於this SO question

private void Application_Deactivated(object sender, DeactivatedEventArgs e) 
{ 
    var dataSvc = SimpleIoc.Default.GetInstance<ICachedDataService>(); 
    var task = Task.Run(async() => { await dataSvc.StoreCachedDataAsync(); }); 
    task.Wait(); 
} 
+0

這是我在我的答案中推薦的「卸載到另一個線程」選項。如果你的'ICachedDataService'是線程安全的,這是最簡單的解決方案。 –

+0

@StephenCleary,啊......太棒了......在發佈我之前我沒有看到你的答案。 –

0

和感謝引用。正如你發現的那樣,可以選擇包裝/踢出任務並嘗試同步等待其完成。

但是......這是一個權宜之計。一旦開始關閉或停用操作,就沒有任何事情可以阻止它的發生,而且沒有任何東西可以擊敗開始的「死亡時鐘」。期。值得注意的是,這同樣適用於Windows Store應用程序中的Suspensions。沒有任何機制可以「購買更多時間」--Windows商店應用程序確實提供了「失敗」,但正如我在帖子中提到的那樣,這些應用程序仍在上述「死亡時鐘」的約束下運行。「

我提起這事,因爲你所提到的:

我和(2)的問題,它仍然不能保證它會 有時間儲存,即使我儘快開始就越好。

當我讀到的關注,或許是表明在應用程序而節省運行啓動「另存爲你去」操作,然後一個場景,一輩子的大事(關閉/關閉)進行。這些終身事件將會對正在進行的保存非常無知,並且應用程序將放棄執行,並且事情將會解除簡單地磨礪到不禮貌的停頓。在這種情況下,保存操作可能會包含一個同步標誌來指示操作正在進行中,然後可以在終生事件內部監視該操作,但是(有可能擊敗死馬)仍然需要意識到整個「死亡時鐘」的事情(加上事情開始變得複雜/複雜)。

最終,如果您的應用發現自己處於保存時間可能比允許時間更長的情況,則可能很重要重新思考遊戲中的確切機制,看看是否有辦法避免這種情況。雖然在這個到期時間內有很多方法可以「異想天開」地玩遊戲,但是到期將會發生。

+0

我並沒有太在意(2)中的死亡時鐘,因爲我在操作系統生命週期事件時運行異步操作。是的,如果允許的時間不夠,你需要重新考慮你的應用程序,也許需要一個後臺任務(或其他) –

相關問題