Windows窗体中的非托管回调问题。访问违规

时间:2011-07-13 17:22:10

标签: c# winforms pinvoke

我遇到了第三方.dll使用非托管回调在c#表单项目中工作的问题。最初程序在第一次调用回调后会崩溃。但是,响应here帮助我解决了这个问题(Cdecl是正确的调用约定)。 C#中的回调定义如下:

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void FrameDelegate(IntPtr lpContext, IntPtr bpData, int nDataSize, int nChannel, int isKeyFrame, int nFrameCnt);

实际的回调如下:

    public void FrameDelegate(IntPtr lpContext, IntPtr bpData, int nDataSize,
        int nChannel, int isKeyFrame, int nFrameCnt)
    {
        lock (ChannelStats)
        {
            ChannelStats.TotalSize += nDataSize;
            ChannelStats.CurrentFileSize += nDataSize;
            ChannelStats.FrameCount++;
        }
        UpdateStatistics();
    }

更新统计功能:

    private void UpdateStatistics()
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new UpdateDelegate(UpdateStatistics));
        }
        else
        {
            lock (ChannelStats)
            {
                FrameCapturedLabel.Text = string.Format("Frames Captured: {0}", ChannelStats.FrameCount);
                TotalCapturedLabel.Text = string.Format("Total Captured: {0} [MB]", (double)ChannelStats.TotalSize / 1000000.0);
                CurrentFileLabel.Text = string.Format("Current File Size: {0} [MB]", (double)ChannelStats.CurrentFileSize / 1000000.0);
                FileCountLabel.Text = string.Format("File Count: {0}", ChannelStats.FileCount); 
            }                      
        }
    }

代码在因访问冲突异常崩溃之前成功运行随机数量的帧(通常为5-15)。不幸的是,这是在远程嵌入式系统上运行的,因此我没有方便的调试器来帮助我。另外值得注意的是:

  • 运行上面的代码,而不调用UpdateStatistics(),工作正常。
  • 在C ++ Win32控制台应用程序中运行类似程序可以正常工作。

所以我的问题:任何可能导致访问冲突的提示?代码中的锁定是否合理,还是完全关闭?

非常感谢任何输入!

修改

ChannelStats变量定义如下:

    private class RecordStatistics
    {
        public Int64 TotalSize { get; set; }
        public Int64 CurrentFileSize { get; set; }
        public Int64 FileCount { get; set; }
        public Int64 FrameCount { get; set; }

        public RecordStatistics()
        {
            TotalSize = 0;
            CurrentFileSize = 0;
            FileCount = 0;
            FrameCount = 0;            
        }
    }

    RecordStatistics ChannelStats;

1 个答案:

答案 0 :(得分:1)

什么是ChannelStats?那是你的班级吗?如果你锁定单独的对象会更好。

private static object _thisLock = new object();

lock (_thisLock)
{
    // Critical code section
}