您不需要调用EndInvoke
;不调用它仅意味着:
- 您无法获得该方法的返回值。
- 在方法执行期间抛出的任何异常都将消失。
听起来您想要“点火并忘记”,所以最简单的方法是使用匿名委托,例如:
var del = new Action(foo.Bar);
del.BeginInvoke(iar =>
{
try
{
del.EndInvoke(iar);
}
catch (Exception ex)
{
}
}, null);
当您执行此代码时,会发生以下情况:
- 为委托分配了一个新线程。
- 线程被赋予委托
del
和匿名委托 (iar => ...
)。
- 线程执行
del
。
- 当执行完成(或发生异常)时,结果或异常被存储,并执行匿名委托。
- 在匿名委托内,当调用
EndInvoke
时,方法的结果将被返回,或者如果发生异常,则抛出异常。
请注意,上面的示例与以下示例非常不同:
// This is pointless and is still, essentially, synchronous.
del.EndInvoke(del.BeginInvoke(null, null));
编辑:你应该总是调用End*
。我从未遇到过不调用它会出现问题的情况,但这是一个实现细节,依赖于未记录的行为。
最后,如果抛出异常,你的解决方案将使进程崩溃,如果你不关心异常,可以简单地将委托传递为null (del.BeginInvoke(myStruct, null, null);
)。因此,作为最终示例,你可能需要的是:
public class A
{
void Foo(S myStruct){...}
void FooAsync(S myStruct)
{
var del = new Action<S>(Foo);
del.BeginInvoke(myStruct, SuppressException, del);
}
static void SuppressException(IAsyncResult ar)
{
try
{
((Action<S>)ar.AsyncState).EndInvoke(ar);
}
catch
{
}
}
}
EndInvoke
,但如果你不这样做,就会导致内存泄漏。https://dev59.com/LHI-5IYBdhLWcg3wta7w?rq=1 - Matt Klein