调用WinAPI EnterCriticalSection触发AccessViolationException问题求助
调用WinAPI的EnterCriticalSection/LeaveCriticalSection触发AccessViolationException的原因及解决方法
核心错误原因
- 未初始化CRITICAL_SECTION结构体:WinAPI的
EnterCriticalSection要求传入一个已完成初始化的CRITICAL_SECTION结构体指针,你代码里直接使用空的IntPtr,相当于传入了无效内存地址,直接触发内存访问异常。 - DllImport签名错误:
EnterCriticalSection和LeaveCriticalSection的参数是指向CRITICAL_SECTION结构体的指针,而非ref IntPtr,错误的参数类型会导致内存访问逻辑混乱。
正确实现代码
using System; using System.Runtime.InteropServices; using System.Windows.Forms; public partial class Form1 : Form { // 定义WinAPI的CRITICAL_SECTION结构体 [StructLayout(LayoutKind.Sequential)] private struct CRITICAL_SECTION { public IntPtr DebugInfo; public int LockCount; public int RecursionCount; public IntPtr OwningThread; public IntPtr LockSemaphore; public UIntPtr SpinCount; } // 正确的WinAPI函数导入签名 [DllImport("kernel32.dll")] private static extern void InitializeCriticalSection(ref CRITICAL_SECTION lpCriticalSection); [DllImport("kernel32.dll")] private static extern void EnterCriticalSection(ref CRITICAL_SECTION lpCriticalSection); [DllImport("kernel32.dll")] private static extern void LeaveCriticalSection(ref CRITICAL_SECTION lpCriticalSection); [DllImport("kernel32.dll")] private static extern void DeleteCriticalSection(ref CRITICAL_SECTION lpCriticalSection); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { try { CRITICAL_SECTION cs = new CRITICAL_SECTION(); // 必须先初始化临界区结构体 InitializeCriticalSection(ref cs); EnterCriticalSection(ref cs); // 此处执行需要线程同步的代码逻辑 LeaveCriticalSection(ref cs); // 临界区不再使用时,释放相关资源 DeleteCriticalSection(ref cs); } catch (Exception exception) { Console.WriteLine(exception.Message); } } }
额外说明
如果是常规.NET开发场景,更推荐使用原生的lock语句或System.Threading.Mutex来实现线程同步,无需直接调用WinAPI,除非有特定的底层交互需求。
内容的提问来源于stack exchange,提问作者dust1x
相关产品推荐
相关产品推荐

