现在的位置: 首页 > 综合 > 正文

[C#]I/O完成端口的实现

2011年12月02日 ⁄ 综合 ⁄ 共 1308字 ⁄ 字号 评论关闭

VC++中我几乎每一个Windows Service都是采用I/O完成端口。至于在C#中如何使用I/O完成端口,一直很少见人提及。 William Kennedy的三篇文章《IOCP Thread Pooling in C#》,对实现这种机制很有帮助,唯一美中不足的是,它只能把int数值压入完成端口,而无法像VC++中那样可以将接口指针/BSTR字符串等等转为OVERLAPPED*。我试了很多遍Marshal.PtrToStructure/StructureToPtr 和StringToBSTR,总是无法成功通过I/O完成端口传递string。

我还曾经用以下这2个函数将string转换为byte[],然后将byte[]转换为NativeOverlapped。总是不行。

System.Threading.NativeOverlapped Ov = new NativeOverlapped();

byte[] btRaw = Str2Arr(strValue);

Ov = (System.Threading.NativeOverlapped)

RawDeserialize(btRaw, typeof(System.Threading.NativeOverlapped));

函数声明如下:

public static byte[] Str2Arr(String s)

{

return (new UnicodeEncoding()).GetBytes(s);

}

public static string Arr2Str(byte[] buffer)

{

return (new UnicodeEncoding()).GetString(buffer, 0, buffer.Length);

}

public static byte[] RawSerialize( object anything )

{

int rawsize = Marshal.SizeOf( anything );

IntPtr buffer = Marshal.AllocHGlobal( rawsize );

Marshal.StructureToPtr( anything, buffer, false );

byte[] rawdatas = new byte[ rawsize ];

Marshal.Copy( buffer, rawdatas, 0, rawsize );

Marshal.FreeHGlobal( buffer );

return rawdatas;

}

public static object RawDeserialize( byte[] rawdatas, Type anytype )

{

int rawsize = Marshal.SizeOf( anytype );

if( rawsize > rawdatas.Length )

return null;

IntPtr buffer = Marshal.AllocHGlobal( rawsize );

Marshal.Copy( rawdatas, 0, buffer, rawsize );

object retobj = Marshal.PtrToStructure( buffer, anytype );

Marshal.FreeHGlobal( buffer );

return retobj;

}

抱歉!评论已关闭.