关于C# 将串行口通信放到事件函数了导致整个函数卡死 160C

void Reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e)
{
var reference = e.FrameReference.AcquireFrame();

        // Color
        using (var frame = reference.ColorFrameReference.AcquireFrame())
        {
            if (frame != null)
            {
                //将图像转入writeablebitmmap
                FrameDescription colorFrameDescription = frame.FrameDescription;
                using (KinectBuffer colorBuffer = frame.LockRawImageBuffer())
                {
                    this.colorBitmap.Lock();

                    // verify data and write the new color frame data to the display bitmap
                    if ((colorFrameDescription.Width == this.colorBitmap.PixelWidth) && (colorFrameDescription.Height == this.colorBitmap.PixelHeight))
                    {
                        frame.CopyConvertedFrameDataToIntPtr(
                            this.colorBitmap.BackBuffer,
                            (uint)(colorFrameDescription.Width * colorFrameDescription.Height * 4),
                            ColorImageFormat.Bgra);

                        this.colorBitmap.AddDirtyRect(new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight));
                    }

                    this.colorBitmap.Unlock();
                }
                if (_mode == CameraMode.Color)
                {
                    camera.Source = frame.ToBitmap();
                }
            }
        }

        // Depth
        using (var frame = reference.DepthFrameReference.AcquireFrame())
        {
            if (frame != null)
            {
                if (_mode == CameraMode.Depth)
                {
                    camera.Source = frame.ToBitmap();
                }
            }
        }

        // Infrared
        using (var frame = reference.InfraredFrameReference.AcquireFrame())
        {
            if (frame != null)
            {
                if (_mode == CameraMode.Infrared)
                {
                    camera.Source = frame.ToBitmap();
                }
            }
        }

        // Body
        using (var frame = reference.BodyFrameReference.AcquireFrame())
        {
            if (frame != null)
            {
                canvas.Children.Clear();

                _bodies = new Body[frame.BodyFrameSource.BodyCount];

                frame.GetAndRefreshBodyData(_bodies);

                foreach (var body in _bodies)
                {
                    if (body.IsTracked)
                    {
                        // COORDINATE MAPPING
                        foreach (Joint joint in body.Joints.Values)
                        {

                            if (joint.TrackingState == TrackingState.Tracked)
                            {
                                // 3D space point
                                CameraSpacePoint jointPosition = joint.Position;

                                // 2D space point
                                System.Windows.Point point = new System.Windows.Point();


                                if (_mode == CameraMode.Color)
                                {
                                    ColorSpacePoint colorPoint = _sensor.CoordinateMapper.MapCameraPointToColorSpace(jointPosition);

                                    point.X = float.IsInfinity(colorPoint.X) ? 0 : colorPoint.X / 2;
                                    point.Y = float.IsInfinity(colorPoint.Y) ? 0 : colorPoint.Y / 2;
                                    //获取肩肘腕,脊椎中间坐标
                                    switch (joint.JointType)
                                    {
                                        case JointType.WristLeft:
                                            WristLeft.X = point.X;
                                            WristLeft.Y = point.Y;
                                            break;
                                        case JointType.ElbowLeft:
                                            ElbowLeft.X = point.X;
                                            ElbowLeft.Y = point.Y;
                                            break;
                                        case JointType.ShoulderLeft:
                                            ShoulderLeft.X = point.X;
                                            ShoulderLeft.Y = point.Y;
                                            break;
                                        case JointType.SpineShoulder:
                                            SpineShoulder.X = point.X;
                                            SpineShoulder.Y = point.Y;
                                            break;
                                        case JointType.ShoulderRight:
                                            ShoulderRight.X = point.X;
                                            ShoulderRight.Y = point.Y;
                                            break;
                                        case JointType.ElbowRight:
                                            ElbowRight.X = point.X;
                                            ElbowRight.Y = point.Y;
                                            break;
                                        case JointType.WristRight:
                                            WristRight.X = point.X;
                                            WristRight.Y = point.Y;
                                            break;
                                        case JointType.ThumbRight:
                                            ThumbRight.X = point.X;
                                            ThumbRight.Y = point.Y;
                                            break;
                                        case JointType.HandLeft:
                                            HandLeft.X = point.X;
                                            HandLeft.Y = point.Y;
                                            break;

                                    }
                                }
                                else if (_mode == CameraMode.Depth || _mode == CameraMode.Infrared) // Change the Image and Canvas dimensions to 512x424
                                {
                                    DepthSpacePoint depthPoint = _sensor.CoordinateMapper.MapCameraPointToDepthSpace(jointPosition);

                                    point.X = float.IsInfinity(depthPoint.X) ? 0 : depthPoint.X / 2;
                                    point.Y = float.IsInfinity(depthPoint.Y) ? 0 : depthPoint.Y / 2;
                                }


                                // Draw 红色圆,直径10
                                Ellipse ellipse = new Ellipse
                                {
                                    Fill = System.Windows.Media.Brushes.Red,
                                    Width = 10,
                                    Height = 10
                                };

                                Canvas.SetLeft(ellipse, point.X - ellipse.Width / 2);
                                Canvas.SetTop(ellipse, point.Y - ellipse.Height / 2);
                                canvas.Children.Add(ellipse);
                            }
                        }
                        DrawHand(body.HandLeftState,HandLeft);
                        lefthandheight = HandLeft.Y;
                        Addangle(lefthandheight,HandLeft);
                        rightshoulderangle = GetAngle(SpineShoulder, ShoulderRight, ElbowRight);
                        rightelbowangle = GetAngle(ShoulderRight, ElbowRight, WristRight);
                        if (elbowrightflag)
                        {
                            DrawingLine(ShoulderRight, ElbowRight);//连接肩肘
                            DrawingLine(ElbowRight, WristRight);//连接肘腕
                            //DrawingLine(WristRight, ThumbRight);
                            //计算肘角度并添加到canvas 
                            //rightwristangle = GetAngle(ElbowRight,WristRight,ThumbRight);

                            Addangle(rightelbowangle, ElbowRight);
                            //Addangle(rightwristangle, WristRight);
                        }

                        if (shoulderrightflag)
                        {
                            DrawingLine(ShoulderRight, ElbowRight);//连接肩肘
                            DrawingLine(SpineShoulder, ShoulderRight);//连接肩和肩中
                            //计算肩角度并添加到canvas

                            Addangle(rightshoulderangle, ShoulderRight);
                        }

                        if (issend)
                        {
                            rightshoulder = Convert.ToInt32(rightshoulderangle+155);
                            rightelbow = Convert.ToInt32(rightelbowangle + 100);
                            lefthigh = Convert.ToInt32(lefthandheight+100);
                            switch (body.HandLeftState)
                            {
                                case HandState.Open:
                                    lefthand = 100;
                                    break;
                                case HandState.Closed:
                                    lefthand = 200;
                                    break;
                                case HandState.Lasso:
                                    lefthand = 300;
                                    break;
                                case HandState.NotTracked:
                                    lefthand = 100;
                                    break;
                                case HandState.Unknown:
                                    lefthand = 100;
                                    break;

                            }
                            srightshoulder = Convert.ToString(rightshoulder);
                            srightelbow = Convert.ToString(rightelbow);
                            slefthigh = Convert.ToString(lefthigh);
                            slefthand = Convert.ToString(lefthand);
                            txtStatus.Text = srightelbow;
                            //com.Write($"s{srightshoulder}{srightelbow}{slefthigh}190{slefthand}");
                            //Thread.Sleep(20);  延时
                            if (flag == 1)
                            {
                                com.Write("s");
                                //Thread.Sleep(5);
                                com.Write(srightshoulder);
                                //Thread.Sleep(5);
                                com.Write(srightelbow);
                                flag = 2;
                            }
                            else if (flag == 2)
                            {
                                com.Write(slefthigh);
                                //Thread.Sleep(5);
                                com.Write("190");
                                flag = 3;
                            }
                            else if (flag == 3)
                            {
                                com.Write(slefthand);
                                //Thread.Sleep(5);
                                flag = 1;
                            }
                            //com.Write("s");  
                            //Thread.Sleep(5);
                            //com.Write($"{srightshoulder}{srightelbow}{slefthigh}190{slefthand}");
                            //com.Write(srightshoulder);
                            //Thread.Sleep(5);
                            // com.Write(srightelbow);
                            //Thread.Sleep(5);
                            // com.Write(slefthigh);
                            //Thread.Sleep(5);
                            //com.Write("190");
                            //Thread.Sleep(5);
                            //com.Write(slefthand);
                           // Thread.Sleep(5);
                        }








                    }
                }
            }
        }
    }
    这是一个Kinect程序 其中这个大函数是一个事件触发函数 我用的是wpf 我想将我数据处理的值通过串行口通信发送过去,但是当发送两个数据的时候就会卡死的了,该怎么解决我这个问题?具体的串行口通信代码都在最后面 前面是一些数据的chu'l

3个回答

事件函数其实是界面线程,这种时间长的工作建议放工作线程

放工作线程同样会卡死,在发送两个数据的时候串行处理,加个锁,发送完一个再发送另外一个。

解决的思路如下:
一:将耗时的读取串口数据以及生产位图的代码放到另外一个线程处理,可以缓存一定帧数(不是要求特别高的话一般20帧足够,一般摄像头的驱动程序FPS达到16人眼基本看不出来卡顿)将缓存的图像放到Queue队列里面,或者其他的数据结构里
二:在UI线程里面去不停的访问缓存然后按顺序绘制图像
备注:按这个思路处理结果的好坏一般在于你缓存帧数的多少,以及你读写串口数据,将串口bit流转换为C#的位图的方法效率的高低,如果你懂C++的话,建议使用C++去处理串口数据绘制成位图,效率会是C#的十几倍,或者使用C#的unsafe代码,也能明显的提升效率

hxycsdn9159
hxycsdn9159 这种问题没有其他特别好的方法,只能根据实际情况去尽可能的优化,你可以看看串口数据出来的图像是按什么压缩格式存储的,例如是YUV的,还是其他什么的,然后自己想办法去写效率更高的解码器去生成图像,解码器效率越高,图像越流畅
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐