【发布时间】:2009-09-27 20:11:32
【问题描述】:
编辑:将实际问题移到顶部。
更新:找到了 Microsoft 的一个示例,最后添加了一些代码。
我的问题是:
- 在同一个委托实例上调用多个 BeginInvoke 调用是否安全,还是我必须为每个正在进行的方法调用构造一个新的委托实例?
- 如果我必须为每个实例构造新实例,有没有办法从 IAsyncResult 值中获取原始委托?
- 除了使用委托之外,还有其他更好的方法可以为我的类添加异步支持吗?
更多信息如下。
我正在为我的一个类添加异步支持,并认为我会做的很简单。
参加这门课:
public class Calculator
{
public Int32 Add(Int32 a, Int32 b)
{
return a + b;
}
}
我想我可以简单地这样做:
public class Calculator
{
private delegate Int32 AddDelegate(Int32 a, Int32 b);
public Int32 Add(Int32 a, Int32 b)
{
return a + b;
}
public IAsyncResult BeginAdd(Int32 a, Int32 b,
AsyncCallback callback, Object obj)
{
return new AddDelegate(Add).BeginInvoke(a, b, callback, obj);
}
public Int32 EndAdd(IAsyncResult ar)
{
return new AddDelegate(Add).EndInvoke(ar);
}
}
这不起作用,因为这两个方法都构造了自己的委托对象,并且 .EndInvoke 调用会检查我调用它的委托实例是否与我最初调用 BeginInvoke 的委托实例相同。
处理这种情况的最简单方法是将引用存储到变量中,如下所示:
public class Calculator
{
private delegate Int32 AddDelegate(Int32 a, Int32 b);
private AddDelegate _Add;
public Calculator()
{
_Add = new AddDelegate(Add);
}
public Int32 Add(Int32 a, Int32 b)
{
return a + b;
}
public IAsyncResult BeginAdd(Int32 a, Int32 b,
AsyncCallback callback, Object obj)
{
return _Add.BeginInvoke(a, b, callback, obj);
}
public Int32 EndAdd(IAsyncResult ar)
{
return _Add.EndInvoke(ar);
}
}
请注意,我完全意识到允许同一类上的多个实例方法同时执行的问题,涉及共享状态等。
更新:我在 Microsoft 的 Asynchronous Delegates Programming Sample 上找到了这个示例。它显示将IAsyncResult 引用转换回AsyncResult 对象,然后我可以通过AsyncDelegate 属性获取原始委托实例。
这是一种安全的方法吗?
也就是说,下面的类可以吗?
public class Calculator
{
private delegate Int32 AddDelegate(Int32 a, Int32 b);
public Int32 Add(Int32 a, Int32 b)
{
return a + b;
}
public IAsyncResult BeginAdd(Int32 a, Int32 b, AsyncCallback callback, Object obj)
{
return new AddDelegate(Add).BeginInvoke(a, b, callback, obj);
}
public Int32 EndAdd(IAsyncResult ar)
{
AddDelegate del = (AddDelegate)((AsyncResult)ar).AsyncDelegate;
return del.EndInvoke(ar);
}
}
【问题讨论】:
标签: c# asynchronous delegates