c# - Application.Run 试图读取或写入受保护的内存
问题描述
简而言之,我的应用程序是一个 Windows 窗体,它具有图片框来显示来自使用 ROI(感兴趣区域)检测手机屏幕的摄像头的实时馈送。
下面是例外
-$exception {System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at System.Drawing.SafeNativeMethods.Gdip.GdipDrawImageRectI(HandleRef graphics, HandleRef image, Int32 x, Int32 y, Int32 width, Int32 height)
at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32 width, Int32 height)
at System.Drawing.Graphics.DrawImage(Image image, Rectangle rect)
at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)} System.AccessViolationException
下面是堆栈跟踪
StackTrace "at System.Drawing.SafeNativeMethods.Gdip.GdipDrawImageRectI(HandleRef graphics, HandleRef image, Int32 x, Int32 y, Int32 width, Int32 height)\r\n at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32 width, Int32 height)\r\n
at System.Drawing.Graphics.DrawImage(Image image, Rectangle rect)\r\n at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)\r\n
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)\r\n
at System.Windows.Forms.Control.WmPaint(Message& m)\r\n
at System.Windows.Forms.Control.WndProc(Message& m)\r\n
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)" string
如果我让我的应用程序在以下行运行,Application.Run(MMI.MainMDI); 将尝试写入或读取受保护的内存;像下面
static void Init()
{
MMI.Data = new CommonDataType();
MMI.MainMDI = new MDIMain();
MMI.MainMDI.Show();
MMI.FrmMain = new FormMain();
MMI.MainMDI.Text = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
MMI.FrmMain.MdiParent = MMI.MainMDI;
MMI.FrmMain.StartPosition = FormStartPosition.Manual;
MMI.FrmMain.Location = new System.Drawing.Point(MMI.MainMDI.ClientRectangle.Location.X, MMI.MainMDI.ClientRectangle.Y);
MMI.FrmMain.Width = MMI.MainMDI.ClientRectangle.Size.Width - 10;
MMI.FrmMain.Show();
GenericMachine.SetMessageLogForm(MMI.FrmMsg);
if (!MMI.Data.Config.LoadConfig())
{
MessageBox.Show("Error Loading Config File Data... Application Will Be Closed");
Environment.Exit(0);
}
MMI.DBCtrl = new MainDBControl();
MMI.DBCtrl.Start();
MMI.DevCtrl = new MainDevControl();
MMI.DevCtrl.Start();
MMI.IOCtrl = new MainIOControl();
MMI.IOCtrl.Start();
MMI.CycleCtrl = new MainCycleControl();
MMI.CycleCtrl.Start();
}
static void DeInit()
{
if (MMI.IOCtrl != null) MMI.IOCtrl.Dispose();
if (MMI.DevCtrl != null) MMI.DevCtrl.Dispose();
if (MMI.DBCtrl != null) MMI.DBCtrl.Dispose();
if (MMI.CycleCtrl != null) MMI.CycleCtrl.Dispose();
EndTask("loadmultipleimages.exe");
EndTask("EXCEL.EXE");
}
static System.Threading.Mutex mutex = new System.Threading.Mutex(true, "Sensata MMI Application");
[STAThread]
static void Main()
{
if (mutex.WaitOne(TimeSpan.Zero, true))
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Init();
Application.Run(MMI.MainMDI);
DeInit();
mutex.ReleaseMutex();
}
else
{
MessageBox.Show("Application Already Running - Only One Instance is Allowed at One Time");
}
}
当我检查堆栈跟踪时,源来自 System.Drawing,我怀疑它来自我的 FORM 类。我认为这是因为即使没有检测到手机屏幕,图片框也会继续运行。因此,基本上我的 formshown 方法将始终刷新并触发事件处理程序 refreshscreen1 方法,因为 bool m_camerachoosen 始终为 true 以确保相机始终显示在 picturebox.Image 上,它会不断循环进入DetectText 函数。有没有办法解决这个尝试读取或写入受保护的内存?我已经面临这个问题将近 1 个月了。
private void FormMain_Shown(object sender, EventArgs e)
{
if (m_screenRefreshTimer1 == null)
{
m_screenRefreshTimer1 = new System.Windows.Forms.Timer();
m_screenRefreshTimer1.Interval = 200;
m_screenRefreshTimer1.Tick += new System.EventHandler(refreshScreen1);
m_screenRefreshTimer1.Start();
}
if (m_screenRefreshTimer2 == null)
{
m_screenRefreshTimer2 = new System.Windows.Forms.Timer();
m_screenRefreshTimer2.Interval = 1000;
m_screenRefreshTimer2.Tick += new System.EventHandler(refreshScreen2);
m_screenRefreshTimer2.Start();
}
}
private void refreshScreen1(object sender, EventArgs e)
{
if (MMI.CycleCtrl == null) return;
m_screenRefreshTimer1.Stop();
txtBoxRisk.Text = "";
txtBoxDateTime.Text = "";
txtBoxMYS.Text = "";
txtboxhint.Text = MMI.Data.Mach.Hint;
txtboxMSG.Text = MMI.Data.Mach.DBMessage;
if (m_Camerachosen)
{
txtboxhint.BackColor = System.Drawing.Color.Aqua;
//md.Hint = "PLEASE PLACE YOUR PHONE AT THE DESIGNATED AREA";
DetectText(myImage);
}
}
private void refreshScreen2(object sender, EventArgs e)
{
m_screenRefreshTimer2.Stop();
m_screenRefreshTimer2.Start();
}
private void startToolStripMenuItem_Click(object sender, EventArgs e)
{
VideoCaptureDevice = new VideoCaptureDevice(filterInfoCollection[comboBox1.SelectedIndex].MonikerString);
VideoCaptureDevice.NewFrame += VideoCaptureDevice_NewFrame;
VideoCaptureDevice.Start();
}
private void VideoCaptureDevice_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Bitmap picboxclone = (Bitmap)eventArgs.Frame.Clone();
myImage = new Image<Bgr, Byte>(picboxclone);
m_Camerachosen = true;
}
private void DetectText(Image<Bgr, byte> img)
{
Image<Bgr, byte> imgclone = img;
Image<Gray, byte> sobel = img.Convert<Gray, byte>().Sobel(1, 0, 3).AbsDiff(new Gray(0.0)).Convert<Gray, byte>().ThresholdBinary(new Gray(90), new Gray(255));
var mask = img.Convert<Gray, byte>().SmoothMedian(3).
ThresholdBinary(new Gray(150), new Gray(255));
Mat SE = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle, new Size(1, 1), new Point(-1, -1));
sobel = sobel.MorphologyEx(Emgu.CV.CvEnum.MorphOp.Dilate, SE, new Point(-1, -1), 1, Emgu.CV.CvEnum.BorderType.Reflect, new MCvScalar(255));
Emgu.CV.Util.VectorOfVectorOfPoint contours = new Emgu.CV.Util.VectorOfVectorOfPoint();
Emgu.CV.Util.VectorOfVectorOfPoint contours2 = new Emgu.CV.Util.VectorOfVectorOfPoint();
Mat m = new Mat();
CvInvoke.FindContours(sobel, contours, m, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);
CvInvoke.FindContours(mask, contours2, m, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);
List<Rectangle> list = new List<Rectangle>();
Rectangle maskrect = new Rectangle();
}
解决方案
推荐阅读
- r - R: How to add legend to a scatter plot with 5 stats differents
- mysql - 如何强制 MySQL 为事务获取表锁?
- javascript - Leafletjs 自定义地图,带有显示多个地图的单个图像 png 文件
- python - 如何在 tkinter 中显示来自 numpy 数组的图像?
- python-2.7 - TensorVariable to Array
- html - 框中的行高度相同
- java - Java 使用 telnet 验证 SMTP 服务器
- asp.net - Change ASP.NET Version of Azure app service
- high-availability - 故障转移 Web 服务器集群角色
- typescript - Check if certain props changed, no indexer