- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我对 C# 和一般编程还是很陌生,但到目前为止我已经做了一些应用程序。只执行一项任务然后退出的普通应用程序已经足够简单,但是让一个系统例如每天拍摄 500 张用户照片给了我更大的挑战。
我的问题是关于 WPF 中的内存消耗。我有以下页面,加载时它会占用越来越多的内存。我尝试使用内存分析器工具并创建了一些快照来尝试解决此问题。但是,我很难理解何时/如何处理对象并确保 GC 负责其余的工作。我遇到特别麻烦的页面之一是:
第 2 页:
using EDSDKLib;
using PhotoBooth.Functions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace PhotoBooth.Pages
{
/// <summary>
/// Interaction logic for Picture.xaml
/// </summary>
public partial class Picture : Page
{
int secondsToWait = 4;
DispatcherTimer dispatcherTimer;
Action<BitmapImage> SetImageAction;
ImageBrush bgbrush = new ImageBrush();
public Picture()
{
InitializeComponent();
// Define steps
Global.CreateSteps(Global.SelectedMenuOrder, this, ((MasterPage)System.Windows.Application.Current.MainWindow).StepsWindow);
// Create TempLocation
Directory.CreateDirectory(Settings.TempLocation);
// Handle the Canon EOS camera
Global.CameraHandler.ImageSaveDirectory = Settings.TempLocation;
SetImageAction = (BitmapImage img) => { bgbrush.ImageSource = img; };
// Configure the camera timer
dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += DispatcherTimer_Tick;
dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 800);
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
// Subscribe to camera events
if (Global.CameraHandler != null)
{
Global.CameraHandler.LiveViewUpdated += CameraHandler_LiveViewUpdated;
Global.CameraHandler.ImageSaved += CameraHandler_ImageSaved;
Global.CameraHandler.CameraSDKError += CameraHandler_CameraSDKError;
}
// Start LiveView
try
{
Console.WriteLine(Global.CameraHandler.IsLiveViewOn);
if (!Global.CameraHandler.IsLiveViewOn)
{
CameraLiveView.Background = bgbrush;
Global.CameraHandler.StartLiveView();
}
}
catch (Exception)
{
// We cannot recover from that kind of errror. Reboot the application
CameraCrashHandler();
}
}
private void CameraTrigger_Click(object sender, RoutedEventArgs e)
{
// The user has clicked the trigger, change the layout
CameraTrigger.Visibility = System.Windows.Visibility.Collapsed;
CameraCountDown.Visibility = System.Windows.Visibility.Visible;
CameraTrigger.IsEnabled = false;
// Start the countdown
secondsToWait = 4;
dispatcherTimer.Start();
Global.WriteToLog("INFO", "Camera shutter pressed... waiting for camera to take picture!");
}
private void DispatcherTimer_Tick(object sender, EventArgs e)
{
// Handles the countdown
switch (secondsToWait)
{
case 4:
CameraTimer3.Foreground = new SolidColorBrush(Colors.White);
Global.PlaySound("pack://application:,,,/Resources/Audio/camera_beep.wav");
break;
case 3:
CameraTimer2.Foreground = new SolidColorBrush(Colors.White);
Global.PlaySound("pack://application:,,,/Resources/Audio/camera_beep.wav");
break;
case 2:
CameraTimer1.Foreground = new SolidColorBrush(Colors.White);
Global.PlaySound("pack://application:,,,/Resources/Audio/camera_beep.wav");
break;
case 1:
CameraTimer0.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/Images/icon_cameraWhite.png"));
Global.CameraFlashEffect(((MasterPage)System.Windows.Application.Current.MainWindow).CameraFlash);
Global.CameraHandler.TakePhoto();
break;
case 0:
CameraTimer0.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/Images/icon_cameraRed.png"));
CameraTimer1.Foreground = (SolidColorBrush)(new BrushConverter().ConvertFrom("#e8234a"));
CameraTimer2.Foreground = (SolidColorBrush)(new BrushConverter().ConvertFrom("#e8234a"));
CameraTimer3.Foreground = (SolidColorBrush)(new BrushConverter().ConvertFrom("#e8234a"));
dispatcherTimer.Stop();
break;
default:
break;
}
secondsToWait--;
}
private void Page_Unloaded(object sender, RoutedEventArgs e)
{
// Stop LiveView
if (Global.CameraHandler.IsLiveViewOn)
{
CameraLiveView.Background = null;
Global.CameraHandler.StopLiveView();
}
// Unsubscribe from events
Global.CameraHandler.LiveViewUpdated -= CameraHandler_LiveViewUpdated;
Global.CameraHandler.ImageSaved -= CameraHandler_ImageSaved;
Global.CameraHandler.CameraSDKError -= CameraHandler_CameraSDKError;
}
#region CameraHandler
void CameraHandler_CameraSDKError(string error)
{
// Handle known errors
Global.WriteToLog("ERROR", "CameraSDKError: " + error);
switch (error)
{
case "0x00008D01":
// Reset cameraTrigger for taking another photo
this.Dispatcher.Invoke((Action)(() =>
{
CameraTrigger.Visibility = System.Windows.Visibility.Visible;
CameraCountDown.Visibility = System.Windows.Visibility.Collapsed;
CameraTrigger.IsEnabled = true;
}));
break;
default:
CameraCrashHandler();
break;
}
}
void CameraHandler_ImageSaved(string img)
{
// Assign image to user
Global.PersonObject.Image = img;
// We have a image, let's navigate to the next page
this.Dispatcher.Invoke((Action)(() =>
{
NavigationService.Navigate(Global.FindPageByString(Global.NavigateManager(this, Functions.Enums.Navigation.Forward)));
}));
}
void CameraHandler_LiveViewUpdated(Stream img)
{
try
{
if (Global.CameraHandler.IsLiveViewOn)
{
using (WrappingStream s = new WrappingStream(img))
{
img.Position = 0;
BitmapImage EvfImage = new BitmapImage();
EvfImage.BeginInit();
EvfImage.StreamSource = s;
EvfImage.CacheOption = BitmapCacheOption.OnLoad;
EvfImage.EndInit();
EvfImage.Freeze();
Application.Current.Dispatcher.Invoke(SetImageAction, EvfImage);
}
}
}
catch (Exception ex)
{
Global.WriteToLog("ERROR", "LiveViewUpdated failed: " + ex.Message);
}
}
static void CameraCrashHandler()
{
// Camera cannot start
Global.WriteToLog("ERROR", "Unkown CameraSDKError. Automatic reboot needed");
MessageWindow mw = new MessageWindow("CameraErrorTitle", "CameraErrorMessage");
mw.ShowDialog();
// We cannot recover from that kind of errror. Reboot the application
System.Windows.Forms.Application.Restart();
System.Windows.Application.Current.Shutdown();
}
#endregion
}
}
第 3 页:
using PhotoBooth.Functions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace PhotoBooth.Pages
{
/// <summary>
/// Interaction logic for PreviewID.xaml
/// </summary>
public partial class PreviewID : Page
{
public PreviewID()
{
InitializeComponent();
// Define steps
Global.CreateSteps(Global.SelectedMenuOrder, this, ((MasterPage)System.Windows.Application.Current.MainWindow).StepsWindow);
// Load image and data
PreviewIDText = GetIDText(Global.PersonObject, PreviewIDText);
PreviewIDCard.Source = GetIDPhoto(Global.PersonObject);
PreviewIDPhoto.Background = new ImageBrush(new BitmapImage(new Uri(Global.PersonObject.Image)));
}
private void PreviewIDRetry_Click(object sender, RoutedEventArgs e)
{
Global.WriteToLog("INFO", "User did not approve the image, retry!");
NavigationService.Navigate(Global.FindPageByString(Global.NavigateManager(this, Functions.Enums.Navigation.Backward)));
}
private void PreviewIDAccept_Click(object sender, RoutedEventArgs e)
{
Global.WriteToLog("INFO", "User approved the image");
NavigationService.Navigate(Global.FindPageByString(Global.NavigateManager(this, Functions.Enums.Navigation.Forward)));
}
public TextBlock GetIDText(Functions.Enums.Person p, TextBlock tb)
{
tb.Text = "";
tb.FontSize = 24;
if (p.Affiliation == Functions.Enums.Affiliation.Employee)
{
// Ansatt
tb.Inlines.Add(new Run(p.FirstName + " " + p.LastName + Environment.NewLine) { FontWeight = FontWeights.Bold, FontSize = 30 });
tb.Inlines.Add(p.Title + Environment.NewLine);
tb.Inlines.Add(p.Department + Environment.NewLine);
tb.Inlines.Add("Ansatt nr: " + p.EmployeeNumber + Environment.NewLine);
}
else
{
// Student
tb.Inlines.Add("Last name: ");
tb.Inlines.Add(new Run(p.LastName + Environment.NewLine) { FontWeight = FontWeights.Bold });
tb.Inlines.Add("First name: ");
tb.Inlines.Add(new Run(p.FirstName + Environment.NewLine) { FontWeight = FontWeights.Bold });
tb.Inlines.Add("Date of birth: ");
tb.Inlines.Add(new Run("dd.mm.yyyy" + Environment.NewLine) { FontWeight = FontWeights.Bold });
tb.Inlines.Add("Studentnr: ");
tb.Inlines.Add(new Run("xxxxxx" + Environment.NewLine) { FontWeight = FontWeights.Bold });
}
return tb;
}
public BitmapImage GetIDPhoto(Functions.Enums.Person p)
{
BitmapImage result;
switch (p.Affiliation)
{
case PhotoBooth.Functions.Enums.Affiliation.Student:
result = new BitmapImage(new Uri("pack://application:,,,/Resources/Images/idcard_student.png"));
break;
case PhotoBooth.Functions.Enums.Affiliation.Employee:
result = new BitmapImage(new Uri("pack://application:,,,/Resources/Images/idcard_employee.png"));
break;
default:
result = new BitmapImage(new Uri("pack://application:,,,/Resources/Images/idcard_student.png"));
break;
}
return result;
}
private void Page_Unloaded(object sender, RoutedEventArgs e)
{
PreviewIDPhoto.Background = null;
}
}
}
虽然大部分是全局的。所有其他页面上都使用了函数,它们似乎很好,因为据我所知,正是这个页面造成了我的大部分麻烦。
这是我的内存性能测试的屏幕截图。
用户从第 1 页导航到第 2 页(或其他页面),据我所知没有问题。内存使用似乎很稳定。
用户使用 LiveView 触发佳能相机(第 2 页)。内存消耗上下波动,但稳定。
用户拍摄图像并进行预览(第 3 页)、重试(返回到第 2 页)、拍摄另一张、重试等等...
每次加载后面的代码时:
是位图图像导致了这个问题吗?如果该代码中没有明显的内容,我应该如何继续测试内存泄漏?
最佳答案
我认为是因为 DispatcherTimer。卸载页面时可能仅停止计时器是不够的,因为 WPF 仍会存储对您的类的引用。卸载页面时尝试注销该事件。
关于c# - 使用页面和 BitmapImage 的 WPF 应用程序中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32125606/
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!