问题描述
如果我想要做一个射后不理的一些code,但还是希望确保我的记忆中被清除(每<一个href=\"http://stackoverflow.com/questions/1712741/why-does-asynchronous-delegate-method-require-calling-endinvoke?rq=1\">Why并异步委托方法调用需要的EndInvoke?),将下面的实现这一目标?
If I want to do a "fire and forget" of some code, but still want to ensure that my memory is cleaned up (per Why does asynchronous delegate method require calling EndInvoke?), will the following achieve that goal?
Action myAction = () => LongRunTime();
myAction.BeginInvoke(myAction.EndInvoke,null);
我环顾四周,但没有看到任何地方使用该模式。相反,人们经常使用的方法annonomoyus作为自己的回调(如)或它们定义实际的回调方法。因为我还没有看到任何人做到这一点,这让我觉得要么不工作或其他原因一个坏主意。
I've looked around but haven't seen that pattern used anywhere. Rather, people use an annonomoyus method as their callback (such as The proper way to end a BeginInvoke?) or they define an actual callback method. Since I haven't seen anyone else do this, it makes me think it either doesn't work or is otherwise a bad idea.
谢谢!
推荐答案
使用方法组转换,而不是代表的是精致, EndInvoke会
仍然会叫上你的动作
。有没有别的做的是,因为这是一个火,忘记打电话。
Using a method group conversion instead of a delegate is fine, the EndInvoke
will still be called in on your Action
. There is nothing else to be done, since this is a fire and forget call.
不幸的是,它是有点难以直接无可辩驳地证明,EndInvoke会被调用,因为动作
为代表,并在BCL,我们不能只是添加了一些类断点
Unfortunately, it's somewhat hard to directly irrefutably prove that EndInvoke is called, since Action
is a delegate and we can't just add a breakpoint on some class in the BCL.
这code会(定期)检查由的BeginInvoke
,这似乎跟踪与否<$ C的返回的IAsyncResult的一些私人领域$ C> EndInvoke会曾被称为尚未:
This code will (periodically) inspect some private field of the IAsyncResult that is returned by BeginInvoke
, which seems to keep track of whether or not EndInvoke
has been called yet:
public partial class MainWindow : Window
{
private Timer _timer = new Timer(TimerCallback, null, 100, 100);
private static IAsyncResult _asyncResult;
public MainWindow()
{
InitializeComponent();
}
static void LongRunTime()
{
Thread.Sleep(1000);
}
void Window_Loaded(object sender, RoutedEventArgs args)
{
Action myAction = () => LongRunTime();
_asyncResult = myAction.BeginInvoke(myAction.EndInvoke, null);
}
static void TimerCallback(object obj)
{
if (_asyncResult != null)
{
bool called = ((dynamic)_asyncResult).EndInvokeCalled;
if (called)
{
// Will hit this breakpoint after LongRuntime has completed
Debugger.Break();
_asyncResult = null;
}
}
}
}
我用双检查SOS ,有没有任何托管内存泄漏。我也尝试过其他一些证据,但他们更详尽的不止这一个,我想。
I've double checked using SOS that there aren't any managed memory leaks. I've also tried several other proofs, but they were more circumstantial than this one, I think.
一些有趣的我在我的调查中发现:在 myAction.BeginInvoke
通话将显示在分析器使用的仪器,但 myAction.EndInvoke
没有。
Some interesting I discovered during my investigation: the myAction.BeginInvoke
call will show up on profilers using instrumentation, but myAction.EndInvoke
does not.
这篇关于C#是action.BeginInvoke(action.EndInvoke,NULL)一个好主意?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!