私は同じことを考えていて、検索のかなり早い段階でこれに出くわしました。私は方法を考え出しました。うまくいけば、これは他の誰かにも役立つでしょう。
問題はawait
、UI スレッドの制御が返され、アプリがクラッシュすることです。延期が必要ですが、それを取得する実際の方法はありません。
私の解決策は、代わりに設定ストレージを使用することです。これをやりたいと思っているほとんどの人は、LittleWatson スタイルの何かをしたいと思っていると思います。 -windows-phone-7.aspx :
namespace YourApp
{
using Windows.Storage;
using Windows.UI.Popups;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
public class LittleWatson
{
private const string settingname = "LittleWatsonDetails";
private const string email = "mailto:?to=you@example.com&subject=YourApp auto-generated problem report&body=";
private const string extra = "extra", message = "message", stacktrace = "stacktrace";
internal static void ReportException(Exception ex, string extraData)
{
ApplicationData.Current.LocalSettings.CreateContainer(settingname, Windows.Storage.ApplicationDataCreateDisposition.Always);
var exceptionValues = ApplicationData.Current.LocalSettings.Containers[settingname].Values;
exceptionValues[extra] = extraData;
exceptionValues[message] = ex.Message;
exceptionValues[stacktrace] = ex.StackTrace;
}
internal async static Task CheckForPreviousException()
{
var container = ApplicationData.Current.LocalSettings.Containers;
try
{
var exceptionValues = container[settingname].Values;
string extraData = exceptionValues[extra] as string;
string messageData = exceptionValues[message] as string;
string stacktraceData = exceptionValues[stacktrace] as string;
var sb = new StringBuilder();
sb.AppendLine(extraData);
sb.AppendLine(messageData);
sb.AppendLine(stacktraceData);
string contents = sb.ToString();
SafeDeleteLog();
if (stacktraceData != null && stacktraceData.Length > 0)
{
var dialog = new MessageDialog("A problem occured the last time you ran this application. Would you like to report it so that we can fix the error?", "Error Report")
{
CancelCommandIndex = 1,
DefaultCommandIndex = 0
};
dialog.Commands.Add(new UICommand("Send", async delegate
{
var mailToSend = email.ToString();
mailToSend += contents;
var mailto = new Uri(mailToSend);
await Windows.System.Launcher.LaunchUriAsync(mailto);
}));
dialog.Commands.Add(new UICommand("Cancel"));
await dialog.ShowAsync();
}
}
catch (KeyNotFoundException)
{
// KeyNotFoundException will fire if we've not ever had crash data. No worries!
}
}
private static void SafeDeleteLog()
{
ApplicationData.Current.LocalSettings.CreateContainer(settingname, Windows.Storage.ApplicationDataCreateDisposition.Always);
var exceptionValues = ApplicationData.Current.LocalSettings.Containers[settingname].Values;
exceptionValues[extra] = string.Empty;
exceptionValues[message] = string.Empty;
exceptionValues[stacktrace] = string.Empty;
}
}
}
それを実装するには、上記のリンクと同じことを行う必要がありますが、URL がダウンした場合に備えてデータがここにあることを確認する必要があります。
App.xaml.cs
コンストラクター (への呼び出しの前this.InitializeComponent()
):
this.UnhandledException += (s, e) => LittleWatson.ReportException(e.Exception, "extra message goes here");
UnhandledException メソッドがすでにある場合は、そこに LittleWatson への呼び出しを投げることができます。
Windows 8.1 を使用している場合は、NavigationFailed 呼び出しも追加できます。これは実際のページ (通常は MainPage.xaml.cs または最初に開いたページ) にある必要があります。
xx.xaml.cs
コンストラクター (任意のページ):
rootFrame.NavigationFailed += (s, e) => LittleWatson.ReportException(e.Exception, "extra message goes here");
最後に、アプリを再度開いたときに電子メールを送信するかどうかをユーザーに確認する必要があります。アプリの既定の Page のコンストラクター (既定: App.xaml.cs が初期化するページ) で:
this.Loaded += async (s, e) => await LittleWatson.CheckForPreviousException();
または、既に使用している場合は、OnLoad メソッドへの呼び出しを追加します。