我的 C# 应用程序出现问题并出现异常

问题描述 投票:0回答:1

我在表单加载 afroge 中使用两个包 afroge 和 ozeki 我希望当我单击设备的按钮时,它应该加载 Ozeki 并捕获图片。捕获图片后,它应该加载到 videoSourcePlayer 当我尝试从后台线程更新 UI 控件时,会发生此错误。我已确定问题出在 Disconnect 方法中,也可能出在代码的其他部分中。

using System.Data;
    using System.Text;
    using Ozeki.Camera;
    using Ozeki.Media;
    using System;
    using System.Windows.Forms;
    using AForge.Video;
    using AForge.Video.DirectShow;
    
using AForge.Imaging;

using System.Drawing;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using FontAwesome.Sharp;
using AForge.Controls;
using AForge.Imaging;
using System.IO;
using System.Drawing.Imaging;

namespace Sojro.Myforms
{
    public partial class Dermascope : Form
    {
        private AForge.Video.DirectShow.FilterInfoCollection videoDevices;
        private AForge.Video.DirectShow.VideoCaptureDevice videoDevice;
        private AForge.Video.DirectShow.VideoCapabilities[] videoCapabilities;
        private AForge.Video.DirectShow.VideoCapabilities[] snapshotCapabilities;
        private AForge.Video.IVideoSource videoSource;

        private SnapshotForm snapshotForm = null;

        Guna.UI2.WinForms.Guna2MessageDialog msgdialog;
        private OzekiCamera _camera;
        //private Ozeki.vide VideoCapabilities[] videoCapabilities;
        //private VideoCapabilities[] snapshotCapabilities;
        //private VideoCaptureDevice _videodevice;
        //private AForge.Video.DirectShow.VideoCaptureDevice videoSources;
        private DrawingImageProvider _Provider;
        private MediaConnector _connector;
        private Zoom zoom;
        private ScreenCapture _ScreenCapture;
        private IVideoSender videoSender;
        private MPEG4Recorder recorder;
        private SnapshotHandler snapshotHandler;
        //private Timer messageBoxTimer;
        string folderNewPath = "";

        //private SnapshotForm snapshotForm = null;

        private ToolTip _toolTip = new ToolTip();
        //private Control _currentToolTipControl = null;
        string recordBtnToolTip = "Record";
        string stopdBtnToolTip = "Disabled";
        string snapshotdBtnToolTip = "Take Snapshot";
        string savedBtnToolTip = "Saving to ";
        bool recording = false;
        private string patientIDInput = "";
        string globalCamera = "";
        string _cameraType = "Camera";
        string _cameraTypes = "Ozeki";
        string _cameras = "CameraOzeki";
        private object sender;
        private string selectedDirectory = "";
        private Form2 customMessageBox;

        private void ShowAutoClosingMessageBox(string message, string caption)
        {
            customMessageBox = new Form2(message, caption);
            customMessageBox.SetMessage(message, caption);
            customMessageBox.Show();

            Timer timer = new Timer();
            timer.Interval = 100; // Set the duration in milliseconds (e.g., 3000 for 3 seconds)
            timer.Tick += (s, e) =>
            {
                timer.Stop();
                customMessageBox.Close();
            };
            timer.Start();

        }
        private void ShowMessageBox(string message)
        {

            MessageBox.Show(message, "Success");

            Timer timer = new Timer();
            timer.Interval = 3000; // 3 seconds
            timer.Tick += (s, e) =>
            {
                timer.Stop();
                /*                MessageBox.Hide();*/ // Close the message box
                                                       // You may need to use MessageBox.Close() or other appropriate method based on your actual MessageBox implementation.
            };
            timer.Start();
        }

        public InternalVideoDeviceInfo AsInternalVideoDeviceInfo { get; }


        public Dermascope(string _vname, string patientIDInput, string _folderPath)
        {
            InitializeComponent();
            this.patientIDInput = patientIDInput;
            this.folderNewPath = _folderPath;
            cmdRecording.MouseEnter += new EventHandler(cmdRecording_MouseEnter);
            cmdRecording.MouseLeave += new EventHandler(cmdRecording_MouseLeave);
            cmdRecordingSave.MouseEnter += new EventHandler(cmdRecordingSave_MouseEnter);
            cmdRecordingSave.MouseEnter += new EventHandler(cmdRecordingSave_MouseLeave);
            _connector = new MediaConnector();
            _Provider = new DrawingImageProvider();
            zoom = new Zoom();
            snapshotHandler = new SnapshotHandler();
            globalCamera = _vname;
            Viewerozeki.SetImageProvider(_Provider);
            zoom = new Zoom();
            snapshotHandler = new SnapshotHandler();
            _camera = new OzekiCamera(globalCamera);
            _toolTip.SetToolTip(this.cmdRecording, recordBtnToolTip);
            _toolTip.SetToolTip(this.cmdRecordingSave, stopdBtnToolTip);
            _toolTip.SetToolTip(this.guna2Button1, snapshotdBtnToolTip);
            folderBrowserDialog1.SelectedPath = AppDomain.CurrentDomain.BaseDirectory;


        }
        private void EnableConnectionControls(bool enable)
        {

            videoResolutionsCombo.Enabled = enable;
            snapshotResolutionsCombo.Enabled = enable;
            connectButton.Enabled = enable;
            disconnectButton.Enabled = !enable;
            triggerButton.Enabled = (!enable) && (snapshotCapabilities.Length != 0);
        }

        // Collect supported video and snapshot sizes
        private void EnumeratedSupportedFrameSizes(AForge.Video.DirectShow.VideoCaptureDevice videoDevice)
        {
            this.Cursor = Cursors.WaitCursor;

            videoResolutionsCombo.Items.Clear();
            snapshotResolutionsCombo.Items.Clear();

            try
            {
                videoCapabilities = videoDevice.VideoCapabilities;
                snapshotCapabilities = videoDevice.SnapshotCapabilities;

                foreach (AForge.Video.DirectShow.VideoCapabilities capabilty in videoCapabilities)
                {
                    videoResolutionsCombo.Items.Add(string.Format("{0} x {1}",
                        capabilty.FrameSize.Width, capabilty.FrameSize.Height));
                }

                foreach (AForge.Video.DirectShow.VideoCapabilities capabilty in snapshotCapabilities)
                {
                    snapshotResolutionsCombo.Items.Add(string.Format("{0} x {1}",
                        capabilty.FrameSize.Width, capabilty.FrameSize.Height));
                }

                if (videoCapabilities.Length == 0)
                {
                    videoResolutionsCombo.Items.Add("Not supported");
                }
                if (snapshotCapabilities.Length == 0)
                {
                    snapshotResolutionsCombo.Items.Add("Not supported");
                }

                videoResolutionsCombo.SelectedIndex = 0;
                snapshotResolutionsCombo.SelectedIndex = 0;
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }


        // New snapshot frame is available
        private void videoDevice_SnapshotFrame(object sender, NewFrameEventArgs eventArgs)
        {
            _cameraType = "Video";
            DermaChecks(sender, null);
        }

      


        private void snapshotForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            snapshotForm = null;
        }

        private void Disconnect()
        {
                if (videoSourcePlayer.VideoSource != null)
            {
                // stop video device
                videoSourcePlayer.SignalToStop();
                videoSourcePlayer.WaitForStop();
                videoSourcePlayer.VideoSource = null;

                if (videoDevice.ProvideSnapshots)
                {
                    videoDevice.SnapshotFrame -= new NewFrameEventHandler(videoDevice_SnapshotFrame);
                }


            }
        }
        private void disconnectButton_Click(object sender, EventArgs e)
        {
            Disconnect();
        }


        private void guna2Panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void guna2CircleButton1_Click(object sender, EventArgs e)
        {

        }
        void recorder_Multiplexfinished(Object sender, VoIPEventArgs<bool> e)
        {
            recorder.MultiplexFinished -= recorder_Multiplexfinished;
            recorder.Dispose();
        }

        private void guna2CircleButton2_Click(object sender, EventArgs e)
        {

        }
       private void guna2Button2_Click(object sender, EventArgs eventArgs)
        {
            guna2Button2.BackgroundImage = global::Sojro.Properties.Resources._4383919;
            if (!string.IsNullOrWhiteSpace(patientIDInput))
            {
                _cameraType = "camera";
                Dermascope_Load(sender, null);

                // Define the folder path where you want to save the image
                string folderPath = folderNewPath; // Replace with your desired folder path

                if (!Directory.Exists(folderPath))
                {
                    Directory.CreateDirectory(folderPath);
                }

                int MaxCount = 5;
                int Count = 0;
                var snapshot = snapshotHandler.TakeSnapshot();

                while (snapshot == null && Count < MaxCount)
                {
                    snapshot = snapshotHandler.TakeSnapshot();
                    Count++;

                    if (snapshot == null)
                    {
                        System.Threading.Thread.Sleep(1000);
                    }
                }

                if (snapshot != null)
                {
                    var img = (System.Drawing.Image)snapshot.ToImage();

                    if (img != null)
                    {
                        int newWidth = 1350; // Replace with your desired width
                        int newHeight = 650; // Replace with your desired height

                        //Resize the image
                        var resizedImg = new Bitmap(img, newWidth, newHeight);

                        // Generate a file name using a custom format
                        string fileName = DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss tt") + ".jpg";
                        string filePath = Path.Combine(folderPath, fileName);
                        resizedImg.Save(filePath, ImageFormat.Jpeg);
                        resizedImg.Dispose();                       
                        guna2HtmlLabel1.Text = "Saved to: " + filePath;
                        ShowMessageBoxNew("Image saved successfully.", "Caption", 3);
                    }
                    else
                    {
                        MessageBox.Show("Failed to capture the snapshot.");
                    }
                }

                _cameraType = "Camera";
                Dermascope_Load(sender, null);
            }
            else
            {
                MessageBox.Show("Please enter a patient ID and select a visual device before saving.");
            }

            guna2Button2.BackgroundImage = global::Sojro.Properties.Resources.image;
        }
        private void DermaChecks(object sender, EventArgs e)
        {
            if (_cameraType != "Camera")
            {
                Disconnect();
                _camera = new OzekiCamera(globalCamera);
                _connector.Connect(_camera.VideoChannel, zoom);
                _connector.Connect(zoom, _Provider);

                //For Recording and SnapShot

                _connector.Connect(zoom, snapshotHandler);

                videoSender = zoom;     //zoom for recording with zoom feature, otherwise _camera.VideoChannel

                zoom.Start();

                Viewerozeki.Start();
                Viewerozeki.Show();
                Viewerozeki.BringToFront();

                _camera.Start();
                Viewerozeki.BringToFront();
                guna2HtmlLabel1.BringToFront();
                if (!string.IsNullOrWhiteSpace(patientIDInput))
                {

                    // Define the folder path where you want to save the image
                    string folderPath = folderNewPath; // Replace with your desired folder path

                    if (!Directory.Exists(folderPath))
                    {
                        Directory.CreateDirectory(folderPath);
                    }

                    int MaxCount = 15;
                    int Count = 0;
                    var snapshot = snapshotHandler.TakeSnapshot();

                    while (snapshot == null && Count < MaxCount)
                    {
                        snapshot = snapshotHandler.TakeSnapshot();
                        Count++;

                        if (snapshot == null)
                        {
                            System.Threading.Thread.Sleep(1000);
                        }
                    }

                    if (snapshot != null)
                    {
                        var img = (System.Drawing.Image)snapshot.ToImage();

                        if (img != null)
                        {
                            int newWidth = 1350; // Replace with your desired width
                            int newHeight = 650; // Replace with your desired height

                            //Resize the image
                            var resizedImg = new Bitmap(img, newWidth, newHeight);

                            // Generate a file name using a custom format
                            string fileName = DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss tt") + ".jpg";
                            string filePath = Path.Combine(folderPath, fileName);
                            resizedImg.Save(filePath, ImageFormat.Jpeg);
                            resizedImg.Dispose();
                            guna2HtmlLabel1.Text = "Saved to: " + filePath;
                            MessageBox.Show("Image saved successfully");
                        }
                        else
                        {
                            MessageBox.Show("Failed to capture the snapshot.");
                        }
                    }

                }
            }
            else
            {
                _cameraTypes = "Ozeki";
                Disconnect();
                videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
                videoDevice = new AForge.Video.DirectShow.VideoCaptureDevice(_camera.Moniker);
                videoCapabilities = videoDevice.VideoCapabilities;
                snapshotCapabilities = videoDevice.SnapshotCapabilities;
                if (videoDevices != null)
                {

                    if ((snapshotCapabilities != null) && (snapshotCapabilities.Length != 0))
                    {
                        videoDevice.ProvideSnapshots = true;

                        videoDevice.SnapshotFrame += new NewFrameEventHandler(videoDevice_SnapshotFrame);
                    }

                    videoSourcePlayer.VideoSource = videoDevice;
                    _camera.Stop();
                    Viewerozeki.SendToBack();
                    videoSourcePlayer.BringToFront();
                    //videoSourcePlayer.NewFrame += videoDevice_SnapshotFrame;
                    videoSourcePlayer.Start();
                    guna2HtmlLabel1.BringToFront();
                    if (!string.IsNullOrWhiteSpace(patientIDInput))
                    {

                        // Define the folder path where you want to save the image
                        string folderPath = folderNewPath; // Replace with your desired folder path

                        if (!Directory.Exists(folderPath))
                        {
                            Directory.CreateDirectory(folderPath);
                        }

                        int MaxCount = 15;
                        int Count = 0;
                        var snapshot = snapshotHandler.TakeSnapshot();

                        while (snapshot == null && Count < MaxCount)
                        {
                            snapshot = snapshotHandler.TakeSnapshot();
                            Count++;

                            if (snapshot == null)
                            {
                                System.Threading.Thread.Sleep(1000);
                            }
                        }

                        if (snapshot != null)
                        {
                            var img = (System.Drawing.Image)snapshot.ToImage();

                            if (img != null)
                            {
                                int newWidth = 1350; // Replace with your desired width
                                int newHeight = 650; // Replace with your desired height

                                //Resize the image
                                var resizedImg = new Bitmap(img, newWidth, newHeight);

                                // Generate a file name using a custom format
                                string fileName = DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss tt") + ".jpg";
                                string filePath = Path.Combine(folderPath, fileName);
                                resizedImg.Save(filePath, ImageFormat.Jpeg);
                                resizedImg.Dispose();
                                guna2HtmlLabel1.Text = "Saved to: " + filePath;
                                MessageBox.Show("Image saved successfully");
                            }
                            else
                            {
                                MessageBox.Show("Failed to capture the snapshot.");
                            }
                        }
                    }
            }
        }
        }

        private void Dermascope_Load(object sender, EventArgs e)
        {
            if (_cameraType != "Camera")
            {
                Disconnect();

                _camera = new OzekiCamera(globalCamera);
                _connector.Connect(_camera.VideoChannel, zoom);
                _connector.Connect(zoom, _Provider);

                //For Recording and SnapShot

                _connector.Connect(zoom, snapshotHandler);

                videoSender = zoom;     //zoom for recording with zoom feature, otherwise _camera.VideoChannel

                zoom.Start();

                Viewerozeki.Show();
                Viewerozeki.BringToFront();
                Viewerozeki.Start();
                _camera.Start();
                Viewerozeki.BringToFront();
                guna2HtmlLabel1.BringToFront();
            }
            else
            {
                Disconnect();
                videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
                videoDevice = new AForge.Video.DirectShow.VideoCaptureDevice(_camera.Moniker);
                videoCapabilities = videoDevice.VideoCapabilities;
                snapshotCapabilities = videoDevice.SnapshotCapabilities;
                if (videoDevices != null)
                {

                    if ((snapshotCapabilities != null) && (snapshotCapabilities.Length != 0))
                    {
                        videoDevice.ProvideSnapshots = true;
                        
                        videoDevice.SnapshotFrame += new NewFrameEventHandler(videoDevice_SnapshotFrame);
                    }

                    videoSourcePlayer.VideoSource = videoDevice;
                    _camera.Stop();
                    Viewerozeki.SendToBack();
                    videoSourcePlayer.BringToFront();
                    //videoSourcePlayer.NewFrame += videoDevice_SnapshotFrame;
                    videoSourcePlayer.Start();
                    guna2HtmlLabel1.BringToFront();

                }
            }

        }
        private void Dermascope_FormClosed(object sender, FormClosedEventArgs e)
        {
            Disconnect();
        }

        private void guna2Button3_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(patientIDInput))
            {
                _cameraType = "video";
                Dermascope_Load(sender, null);

                using (SaveFileDialog folderBrowserDialog = new SaveFileDialog())
                {
                    string folderName = patientIDInput;
                    folderBrowserDialog.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
                    folderBrowserDialog.FileName = folderName;

                    if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
                    {
                        if (folderBrowserDialog.FileName != "")
                        {
                            string filePathFolder = folderBrowserDialog.FileName;

                            // Get the directory of the selected file
                            string directoryPath = Path.Combine(Path.GetDirectoryName(filePathFolder), folderName);

                            // Check if the directory exists, if not, create it
                            if (!Directory.Exists(directoryPath))
                            {
                                Directory.CreateDirectory(directoryPath);
                            }

                            var img = (System.Drawing.Image)snapshotHandler.TakeSnapshot().ToImage();

                            if (img != null)
                            {
                                // Generate a file name using a custom format
                                string fileName = DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss tt") + ".jpg";
                                string filePath = Path.Combine(directoryPath, fileName);

                                // Save the image in the created folder
                                img.Save(filePath, ImageFormat.Jpeg);
                                img.Dispose();

                                MessageBox.Show("Image saved successfully.");
                                guna2HtmlLabel1.Text = "Saved to: " + directoryPath;
                            }
                            else
                            {
                                MessageBox.Show("Failed to capture the snapshot.");
                            }

                            //MessageBox.Show("File saved successfully.");
                        }
                    }
                }
            }
            else
            {
                MessageBox.Show("Please enter a patient ID and select a visual device before saving.");
            }
        }

      


        private async void ShowMessageBoxNew(string message, string title, int timeout)
        {
            //int countdown = 3;
            
            // Create a label to display the countdown
            Label messageLabel = new Label
            {
                Text = $"{message}",
                Font = new System.Drawing.Font("Microsoft Sans Serif", 13),
                AutoSize = true,
                TextAlign = ContentAlignment.MiddleCenter
            };

            int centerX = (150 - messageLabel.Width) / 2;
            int centerY = (100 - messageLabel.Height) / 2;

            // Set the label's location
            messageLabel.Location = new System.Drawing.Point(centerX, centerY);


            // Create a new form to host the label
            Form countdownForm = new Form();
            countdownForm.FormBorderStyle = FormBorderStyle.None;
            countdownForm.Size = new System.Drawing.Size(400, 150);
            countdownForm.StartPosition = FormStartPosition.CenterScreen;

            countdownForm.Controls.Add(messageLabel);

            // Show the form
            countdownForm.Show();            

            // Perform the countdown
            for (int i = timeout; i > 0; i--)
            {
                await Task.Delay(1000); // Wait for 1 second
                messageLabel.Text = $"{message}";                
            }


        }


        private void connectButton_Click(object sender, EventArgs e)
        {
            if (videoDevice != null)
            {

                if ((snapshotCapabilities != null) && (snapshotCapabilities.Length != 0))
                {
                    videoDevice.ProvideSnapshots = true;

                    videoDevice.SnapshotFrame += new NewFrameEventHandler(videoDevice_SnapshotFrame);
                }

                EnableConnectionControls(false);

                videoSourcePlayer.VideoSource = videoDevice;
                videoSourcePlayer.Start();
            }

        }

    }
} 

异常的堆栈跟踪

System.InvalidOperationException
  HResult=0x80131509
  Message=Cross thread access to the control is not allowed.
  Source=AForge.Controls
  StackTrace:
   at AForge.Controls.VideoSourcePlayer.CheckForCrossThreadAccess()
   at AForge.Controls.VideoSourcePlayer.SignalToStop()
   at Sojro.Myforms.Dermascope.Disconnect() in F:\babar\babar\Sojro\Myforms\Dermascope.cs:line 451
   at Sojro.Myforms.Dermascope.DermaChecks(Object sender, EventArgs e) in F:\babar\babar\Sojro\Myforms\Dermascope.cs:line 669
   at Sojro.Myforms.Dermascope.videoDevice_SnapshotFrame(Object sender, NewFrameEventArgs eventArgs) in F:\babar\babar\Sojro\Myforms\Dermascope.cs:line 221
   at AForge.Video.DirectShow.VideoCaptureDevice.OnSnapshotFrame(Bitmap image)at AForge.Video.DirectShow.VideoCaptureDevice.Grabber.BufferCB(Double sampleTime, IntPtr buffer, Int32 bufferLen)
c# camera buttonclick aforge ozeki
1个回答
0
投票

线程安全:确保所有UI更新都在UI线程上完成。使用 InvokeRequired 和 Invoke。您遇到的情况可能与多线程应用程序中的常见问题有关,尤其是在尝试与主 UI 线程以外的线程中的 UI 元素进行交互时。

要解决此问题,您需要确保任何 UI 更新都在 UI 线程上执行。在 Windows 窗体中,这通常是使用 Invoke 方法完成的。以下是解决问题的一般方法:

  • 检查跨线程访问:在更新任何 UI 元素之前,检查是否从非 UI 线程调用更新。

  • 使用Invoke方法:如果更新来自非UI线程,则使用Invoke方法在UI线程上执行更新。

以下是如何执行此操作的简单示例:


// Assuming 'this' is a Form or Control
if (this.InvokeRequired)
{
    this.Invoke(new MethodInvoker(() => {
        // Update your UI controls here
    }));
}
else
{
    // Update your UI controls directly here
}

事件处理和断开连接逻辑:在 Disconnect 方法中,您将停止视频源播放器并取消订阅 SnapshotFrame 事件。这是一个很好的做法,因为它可以确保正确释放资源。确保在必要时应用类似的逻辑,以避免内存泄漏或锁定资源。

快照处理:各种方法(如 DermaChecks 和guna2Button2_Click)中的快照处理逻辑涉及捕获快照然后对其进行处理。确保此进程不会阻塞 UI 线程。如果这是一个耗时的过程,请考虑使用异步编程模式(如 Task.Run)在后台执行这些操作。

UI反馈:在操作进行时向用户提供反馈,特别是对于捕获和保存快照之类的操作,这可能需要一些时间。

错误处理:在方法中实现错误处理,尤其是涉及 I/O 操作或外部库调用的方法。这将有助于优雅地管理意外情况。

重构和组织:您的代码可以从一些重构中受益。例如,捕获和保存图像的逻辑似乎在多个地方重复(DermaChecks、guna2Button2_Click 等)。考虑为此功能创建一个单独的方法,以避免代码重复并增强可维护性。

调试:如果遇到特定错误或意外行为,请使用调试工具单步执行代码并在运行时检查变量。这可以帮助确定哪里出了问题。

© www.soinside.com 2019 - 2024. All rights reserved.