我希望在程序结束时将一些异常数据(如果存在)发布到服务器上。
我有一个在主窗口视图模型析构函数上触发的析构函数..
我跑了这个:
~ProgramWizardViewModel()
{
if ((Program.Errors.Count > 0)
&& (WizardData?.User != null))
{
string errorsText = string.Format(string.Join("\n", Program.Errors));
WizardData.client.UploadExceptionReport(errorsText);
}
}
WizardData.client有一个方法UploadExceptionReport(我从SO复制)
public void UploadExceptionReport(String s)
{
using (var client = new HttpClient())
{
var uri = new Uri(Program.ServerUri + "api/exception_report");
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("exception_string", s)
});
var result = client.PostAsync(uri, content).Result;
string resultContent = result.Content.ReadAsStringAsync().Result;
Console.WriteLine(resultContent);
}
}
但是在client.PostAsync中,调试完全停止,没有例外,并返回:
程序'[3364] Program.vshost.exe'已退出,代码为0(0x0)。
我猜这是因为异步的方式。 POST使一个线程发送它的请求,但析构函数最终确定,对象在执行之前就会丢失。
那么:什么是在程序关闭时发布这些数据的好方法? 这段代码失败的原因是什么?
答案 0 :(得分:2)
你在错误的地方做这件事。
您应该覆盖OnFormClosing方法或为OnClosing事件设置处理程序。
这样做的原因是您不需要在用户界面中出现任何随机的怪异 - 您尝试执行的日志记录应该在之间在程序(或用户)之间发生调用“关闭”,但在表单从视图中消失之前。您甚至可以将鼠标指针更改为“Timer”。如果您执行日志记录异步,请考虑是否在发生DoEvents时重复调用DoEvents,以防止UI在HTTP请求需要一段时间后显示已锁定。
OnFormClosing:https://msdn.microsoft.com/en-us/library/system.windows.forms.form.onformclosing(v=vs.110).aspx
OnClosing:https://msdn.microsoft.com/en-us/library/system.windows.forms.form.closing(v=vs.110).aspx
DoEvents:https://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents(v=vs.110).aspx
答案 1 :(得分:0)
尝试将其设为异步。
~ProgramWizardViewModel()
{
if ((Program.Errors.Count > 0)
&& (WizardData?.User != null))
{
string errorsText = string.Format(string.Join("\n", Program.Errors));
WizardData.client.UploadExceptionReport(errorsText).Wait();
}
}
和
public async Task UploadExceptionReport(String s)
{
using (var client = new HttpClient())
{
var uri = new Uri(Program.ServerUri + "api/exception_report");
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("exception_string", s)
});
var result = await client.PostAsync(uri, content);
string resultContent = await result.Content.ReadAsStringAsync();
Console.WriteLine(resultContent);
}
}
也许现在析构函数将等待http客户端异步任务完成。