【发布时间】:2012-04-04 04:47:12
【问题描述】:
我有一个 Visual Studio 2008 C# .NET 3.5 类,它提供对本机库的访问。该库有一个 Register 方法,允许用户指定将在某些事件上激活的回调。我在下面提供了一个 C# 实现:
internal class MyLibHandle : SafeHandleZeroOrMinusOneIsInvalid { /*...*/ }
internal static class NativeMethods
{
public delegate void OnSomeEventDelegate (FOO foo, IntPtr user);
[DllImport("MyLib.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.U1)]
public static extern bool MyLib_Register(MyLibHandle handle, OnSomeEventDelegate callback, IntPtr user);
}
public class MyWrappedLib : IDisposable
{
private MyLibHandle handle_;
private event EventHandler<OnSomeEventArgs> some_event_int_;
public event EventHandler<OnSomeEventArgs> SomeEvent
{
add
{
if (some_event_int_ == null)
{
if (!NativeMethods.MyLib_Register(handle_, ReceivedSomeEvent, IntPtr.Zero))
throw new Win32Exception(Marshal.GetLastWin32Error());
}
some_event_int_ += value;
}
remove
{
some_event_int_ -= value;
if (some_event_int_ == null)
{
if (!NativeMethods.MyLib_DeRegister(handle_, -1))
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
}
private void ReceivedSomeEvent(FOO foo, IntPtr user)
{
OnSomeEvent(new OnSomeEventArgs() { foo = foo });
}
protected virtual void OnBeacon(OnSomeEventArgs args)
{
EventHandler<OnSomeEventArgs> evt = some_event_int_;
if (evt != null)
evt(this, args);
}
}
这可行,但我收到了一些不祥的警告
warning : CA1065 : Microsoft.Design : 'MyWrappedLib.SomeEvent.add(EventHandler<OnSomeEventArgs>)' creates an exception of type 'Win32Exception', an exception type that should not be raised in this type of method.
warning : CA2122 : Microsoft.Security : 'MyWrappedLib.SomeEvent.add(EventHandler<OnSomeEventArgs>)' calls into 'Marshal.GetLastWin32Error()' which has a LinkDemand. By making this call, 'Marshal.GetLastWin32Error()' is indirectly exposed to user code.
处理这种情况的推荐方法是什么?我应该创建一个方法来处理事件订阅而不是传统的添加吗?消除;访问器?
谢谢
【问题讨论】:
标签: c# events delegates callback