Mat*_*ein 13 c# delegates asynchronous
如果我想对某些代码进行"一劳永逸",但仍希望确保清理我的内存(为什么异步委托方法需要调用EndInvoke?),以下是否会实现这一目标?
Action myAction = () => LongRunTime();
myAction.BeginInvoke(myAction.EndInvoke,null);
Run Code Online (Sandbox Code Playgroud)
我环顾四周,但没有看到任何地方使用过的模式.相反,人们使用annonomoyus方法作为他们的回调(例如结束BeginInvoke的正确方法?)或者他们定义一个实际的回调方法.由于我没有看到其他人这样做,这让我觉得它要么不起作用,要么是一个坏主意.
谢谢!
Tho*_*rin 13
使用方法组转换而不是委托是可以的,EndInvoke仍然会在您的上面调用Action.没有别的事情要做,因为这是一场火灾和忘记的召唤.
不幸的是,直接无可辩驳地证明EndInvoke被调用有点困难,因为它Action是一个委托,我们不能只在BCL中的某个类上添加断点.
此代码将(定期)检查返回的IAsyncResult的某个私有字段BeginInvoke,这似乎跟踪是否EndInvoke已调用:
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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我使用SOS进行了双重检查,发现没有任何托管内存泄漏.我也尝试了其他一些证据,但我认为它们比这个证据更具间接性.
我在调查期间发现了一些有趣的内容:myAction.BeginInvoke调用将显示在使用仪器的分析器上,但myAction.EndInvoke不会.
| 归档时间: |
|
| 查看次数: |
15604 次 |
| 最近记录: |