我遇到了第三方.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)。不幸的是,这是在远程嵌入式系统上运行的,因此我没有方便的调试器来帮助我。另外值得注意的是:
所以我的问题:任何可能导致访问冲突的提示?代码中的锁定是否合理,还是完全关闭?
非常感谢任何输入!
修改
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;
答案 0 :(得分:1)
什么是ChannelStats?那是你的班级吗?如果你锁定单独的对象会更好。
private static object _thisLock = new object();
lock (_thisLock)
{
// Critical code section
}