我一直在想同样的事情,并且在搜索的早期就偶然发现了这一点。我想出了一个方法,希望这对其他人也有用。
问题是await
返回对 UI 线程的控制和应用程序的崩溃。您需要延期,但没有真正的方法可以得到延期。
我的解决方案是改用设置存储。我假设大多数想要这样做的人都想做一些 LittleWatson 风格的事情,所以这里有一些从http://blogs.msdn.com/b/andypennell/archive/2010/11/01/error-reporting-on修改的代码-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 方法,请添加对它的调用。