gpt4 book ai didi

C# action.BeginInvoke(action.EndInvoke,null) 是个好主意吗?

转载 作者:可可西里 更新时间:2023-11-01 08:09:12 24 4
gpt4 key购买 nike

如果我想对某些代码进行“即发即忘”,但仍想确保我的内存被清理(根据 Why does asynchronous delegate method require calling EndInvoke? ),下面的方法是否可以实现该目标?

Action myAction = () => LongRunTime();
myAction.BeginInvoke(myAction.EndInvoke,null);

我环顾四周,但没有看到任何地方使用过这种模式。相反,人们使用 annonomoyus 方法作为他们的回调(例如 The proper way to end a BeginInvoke? )或者他们定义一个实际的回调方法。由于我还没有看到其他人这样做,所以我认为它要么行不通,要么是个坏主意。

谢谢!

最佳答案

使用方法组转换而不是委托(delegate)是可以的,EndInvoke 仍会在您的Action 中调用。没有其他事情要做,因为这是一个火了就不管的电话。

不幸的是,直接无可辩驳地证明调用了 EndInvoke 有点困难,因为 Action 是一个委托(delegate),我们不能只在 BCL 中的某个类上添加断点。

此代码将(定期)检查由 BeginInvoke 返回的 IAsyncResult 的一些私有(private)字段,这似乎跟踪 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;
}
}
}
}

我已经使用 SOS 仔细检查过没有任何托管内存泄漏。我还尝试了其他几个证据,但我认为它们比这个更具体。

我在调查过程中发现了一些有趣的事情:myAction.BeginInvoke 调用将显示在使用检测的分析器上,但 myAction.EndInvoke 不会。

关于C# action.BeginInvoke(action.EndInvoke,null) 是个好主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15967574/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com