回调成功的时候赋值msult都没问题,但是为啥我定时器30MS轮询那个方法去访问msult总是直接return 告诉我这个是个null

C# 开发相关问题,实在是看不明白了 WPF开发

        private Result1v1 m_result1v1 = null;
                m_timerUpdateImage = new System.Windows.Threading.DispatcherTimer();
                m_timerUpdateImage.Tick += new EventHandler(OnUpdateImage);
                m_timerUpdateImage.Interval = new TimeSpan(0, 0, 0, 0, 30);
                m_timerUpdateImage.Start();
        private void OnUpdateImage(object sender, EventArgs e)
        {

            notifyClientResult();

        }
 private void notifyClientResult()
        {
            switch (m_work)
            {
 
                case Work.Recognition1v1:
                    notify1v1Result();
                    break;
                default:
                    break;
            }
        }
        private void notify1v1Result()
        {

            Result1v1 result;
            lock (m_locker1v1Result)
            {
                if (m_result1v1 == null)
                {
                    Console.WriteLine("m result为空,到这就不对了");
                    return;
                }
....
}}
//还有一个回调函数,是外部的SDK成功时调的回调,会赋值m_result1v1
        private void face_verify_succeed_delegate(Single score, IntPtr face_data, int face_h, int face_w, IntPtr frame_data, int frame_h, int frame_w)
        {
           // Debug.Assert(m_work == Work.Recognition1v1);

            lock (m_locker1v1Result)
            {
                //if (m_result1v1 != null && m_result1v1.finished)
                //  throwError(-1);
                Console.WriteLine("人脸比对成功了,得分是"+score.ToString());
                m_result1v1 = new Result1v1();
                m_result1v1.photo = new byte[face_h * face_w * 3];
                m_result1v1.frame = new byte[frame_h * frame_w * 3];
                Marshal.Copy(face_data, m_result1v1.photo, 0, face_h * face_w * 3);
                Marshal.Copy(frame_data, m_result1v1.frame, 0, frame_h * frame_w * 3);
                m_result1v1.score = score;
                Console.WriteLine("人脸比对成功了,得分是" + m_result1v1.score.ToString());
                m_result1v1.finished = true;
                m_result1v1.face_height = face_h;
                m_result1v1.face_width = face_w;
                m_result1v1.frame_height = frame_h;
                m_result1v1.frame_width = frame_w;
            }
            DbgOut("done");
        }
........

回调成功的时候赋值msult都没问题,但是为啥我定时器30MS轮询那个方法去访问msult总是直接return 告诉我这个是个null,是我的锁用得不对吗? 为啥m_sult这个对象会无缘无故变成null啊

拿掉定时器,你无非是想知道有没有结果,那就让他自己告诉你就是了
直接用下面这个就是
System.Threading.Channels

ps:官方出品,net4.62以上版本皆可用,你nuget他就行。至于这东西怎么用自己百度,因为这个原本就是官方库资料多的很,原本早就应该被大众熟悉和应用的,只是那个园子整体不干正事,专门带着新人门跳坑。(包括你这提问,也是园子喜欢写文章告诉你们的,定时器啊,lock啊都是园子们喜欢的题材)

另外说句题外话,外部C++ dll回调最好写成静态的,因为类成员对象跟gc绑着。所以偶尔会发生gc释放,C++回调异常,或者gc移动内存指针,C++回调异常

m_locker1v1Result 在哪里定义的,这个你贴的代码不完整啊

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    由于缺少完整的代码和定时器的相关处理,无法给出准确的解决方案。但是,以下是可能导致无法轮询访问m_sult对象的原因:

    1. 程序中出现了空指针,例如m_sult被初始化为NULL或在某个时刻被赋值为NULL,导致无法访问对象。
    2. 在多线程环境中,如果没有正确处理对象锁的使用,可能会发生竞争条件,导致m_sult对象被其他线程修改或释放,从而无法访问对象。
    3. 如果程序中使用了异步回调,在回调执行完成之前,m_sult可能还未被赋值,此时尝试访问该对象可能导致null异常。
    4. 其他可能存在的bug或者代码逻辑错误,需要对代码进行全面地检查和调试。

    在进行排查时,可以使用调试器、日志输出等手段对代码进行全方位的调试,逐步缩小问题出现的范围。对于可能存在的锁问题,需要对锁的使用场景进行仔细分析,确定锁的粒度和范围,并且确保锁的释放顺序和获取顺序一致,避免死锁问题。针对无法访问对象的问题,可以使用断言或者异常处理的方式进行及时的提示和处理,帮助快速发现和解决问题。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^