[英]Async task memory leak
我只是对在设备上运行的UWP应用程序进行性能分析,以尝试诊断观察到的内存泄漏。
使用快照,我发现我有越来越多的Task对象,这些对象似乎是由引发日志事件的内部组件创建的。
这是一个比较快照和看起来正在泄漏的对象的屏幕截图。
我有两个绑定到OnLogReceived的事件侦听器; 他们看起来像这样:
ApplicationContext.Current.LoggerContext.OnLogReceived += LoggerContext_OnLogReceived;
ApplicationContext.Current.LoggerContext.OnLogReceived += (logLevel, timestamp, message) => RemoteLogHelper.SendMessage(logLevel, message);
这是第一个处理程序的定义。 这将在屏幕上的滚动查看器中显示日志,并将条目截断为1000。LogEntryModel通过ViewModelBase实现INotifyPropertyChanged,以避免泄漏PropertyChanged。
private async void LoggerContext_OnLogReceived(LogLevel logLevel, DateTime timestamp, string message)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
var entry = new LogEntryModel
{
Message = string.Format("[{0:h:mm:ss tt}] {1}", timestamp, message)
};
entry.SetDispatcher(ApplicationContext.Current.Dispatcher);
lock (ApplicationContext.Current.ReceiverDetails.Log)
{
ApplicationContext.Current.ReceiverDetails.Log.Add(entry);
while (ApplicationContext.Current.ReceiverDetails.Log.Count > 1000)
{
ApplicationContext.Current.ReceiverDetails.Log.RemoveAt(0);
}
}
if (!uxPreventLogFromScrolling.IsChecked ?? false)
{
LogScrollViewer.ChangeView(0.0d, double.MaxValue, 1.0f);
}
});
}
发送消息处理程序(2)会将日志行发送到远程API(如果为此设备启用了远程日志记录)以进行调试。 我们希望这是一发不可收拾的事情,这意味着我们不想等待日志成功发送到端点。
public static async void SendMessage(LogLevel logLevel, string message)
{
if (!IsEnabled())
return;
await Task.Run(() =>
{
try
{
ApplicationContext.Current.ApiClient.PostAsync<LogRequestModel, object>("/api/remote/receiver/log", new LogRequestModel { MacAddress = MacAddress, Text = message });
}
catch (Exception)
{
; // we tried
}
});
}
将此方法更改为以下定义不会更改行为(仍然显示相似的快照结果)
public static async void SendMessage(LogLevel logLevel, string message)
{
if (!IsEnabled())
return;
try
{
await ApplicationContext.Current.ApiClient.PostAsync<LogRequestModel, object>("/api/remote/receiver/log", new LogRequestModel { MacAddress = MacAddress, Text = message });
}
catch (Exception)
{
; // we tried
}
}
谁能说出泄漏的原因以及如何避免泄漏? 通过研究,我认为我不需要处理任务,这里的所有事情看起来都应该在完成后自动清理。 但是,我可以肯定地看到内存使用量正在增长,快照证实了这一点。
如果有人遇到此问题,请在此处记录答案。 我们使用.ContinueWith来防止任务泄漏
资料来源: http : //stackoverflow.com/a/15524271/647728
public static void SendMessage(LogLevel logLevel, string message)
{
if (!IsEnabled())
return;
//http://stackoverflow.com/a/15524271/647728
ApplicationContext.Current.ApiClient.PostAsync<LogRequestModel, object>("/api/remote/receiver/log", new LogRequestModel { MacAddress = MacAddress, Text = message }).ContinueWith(t => { }, TaskContinuationOptions.OnlyOnFaulted);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.