当前位置: 首页 > 编程语言 > C#

分享_1116

时间:2023-04-10 19:18:19 C#

在C#背景下使用LockFileEX我正在尝试在我的C#应用程序中实现块文件锁定。如果内置的FileStream.Lock方法无法获取锁,则会引发异常。底层LockFile方法返回一个状态代码,但我不想使用自旋锁来等待文件解锁。问题是否有人在C#中有任何代码片段显示如何使用等待句柄正确构造OVERLAPPED结构并将其传递给LockFileEx并等待操作完成?我试图避免使用Overlapped.Pack方法,因为它们不安全,但主要是因为它们需要IOCompletionCallback,这不是我想要实现的。我有声明,但是OverLapped结构的构造和使用似乎有点复杂。注意:我知道我需要手动修复重叠结构,直到等待完成。我目前的代码如下:ManualResetEventevt=newManualResetEvent(false);OVERLAPPED重叠=newOVERLAPPED();overlapped.OffsetLow=offsetLow;overlapped.OffsetHigh=offsetHigh;overlapped.hEvent=evt.SafeHandle;GCHandleh=GCHandle.Alloc(重叠,GCHandleType.Pinned);inthr=Win32.LockFileEX(_handle,LockFlags.Exclusive,0,offsetLow,offsetHigh,GCHandle.ToIntPtr(h));如果(hr==0){interror=Marshal.GetLastWin32Error();如果(错误=Win32.ERROR_IO_PENDING){evt.WaitOne();}else{//ohpoo}}解析度最后按我的意愿工作的代码是:[StructLayout(LayoutKind.Sequential)]publicstructOVERLAPPED{publicuintinternalLow;公共单位内部高;publicuintoffsetLow;publicuintoffsetHigh;公共IntPtrhEvent;}[DllImport("Kernel32.dll",SetLastError=true)]privatestaticexternboolLockFileEx(SafeFileHandlehandle,uintflags,uintreserved,uintcountLow,uintcountHigh,refOVERLAPPEDoverlapped);私有结构LOCKFILE_EXCLUSIVE_LOCK=0x00000002;publicstaticvoidLock(FileStreamstream,ulongoffset,ulongcount){uintcountLow=(uint)count;uintcountHigh=(uint)(计数>>32);OVERLAPPEDoverlapped=newOVERLAPPED(){internalLow=0,internalHigh=0,offsetLow=(uint)offset,offsetHigh=(uint)(offset>>32),hEvent=IntPtr.Zero,};if(!LockFileEx(stream.SafeFileHandle,LOCKFILE_EXCLUSIVE_LOCK,0,countLow,countHigh,refoverlapped)){//TODO:throwanexception}}此代码阻塞,直到可以获取该区域的独占锁以下应该是“非常接近”到“好的解决方案”。我真正不喜欢的唯一部分是使用反射来访问mscorlib内部方法,但该方法在将Win32错误代码转换为IOExceptions方面做得非常出色。由于您已经拥有NativeOverlapped*不安全代码,因此NativeOverlapped*权限不是问题。可以通过创建SafeFileLockHandle或类似物来进一步改进,以提供轻量级IDisposable对象来解锁从CriticalFinalizerObject派生的文件。私有结构LOCKFILE_EXCLUSIVE_LOCK=0x00000002;私有静态只读操作WinIOError;静态Win32Native(){BindingFlagsbindingAttr=BindingFlags.Static|BindingFlags.公共|BindingFlags.NonPublic;varwinIOErrorMethod=typeof(string).Assembly.GetType("System.IO.__Error").GetMethod("WinIOError",bindingAttr,null,Type.EmptyTypes,null);WinIOError=(Action)Delegate.CreateDelegate(typeof(Action),winIOErrorMethod);}publicstaticvoidLockFile(SafeFileHandlehandle,boolexclusive,longoffset,longlength,Actionaction){if(handle==null)thrownewArgumentNullException("handle");if(handle.IsInvalid)thrownewArgumentException("指定了一个无效的文件句柄。","handle");如果(偏移>32);overlapped.OffsetLow=(int)offset;IOCompletionCallback回调=(errorCode,numBytes,nativeOverlapped)=>{try{action();}最后{Overlapped.Free(nativeOverlapped);}};NativeOverlapped*native=overlapped.Pack(回调,空);uint标志=独占?LOCKFILE_EXCLUSIVE_LOCK:0;if(!LockFileEx(handle,flags,0,(int)length,(int)(length>>32),native)){Overlapped.Free(native);WinIOError();}}[DllImport("kernel32.dll",SetLastError=true)]privatestaticunsafeexternboolLockFileEx(SafeFileHandlehandle,uintflags,uintmustBeZero,intcountLow,intcountHigh,NativeOverlapped*overlapped);Reflector有答案(pinvoke.net和http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/7217a8d3-d36d-43c9-ad4f-ad638a9ac1de都有说法)以上是C#学习教程:LockFileEX在C#中分享的所有内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注——本文收集自网络,不代表立场。如涉及侵权请点击维权联系管理员删除如需转载请注明出处: