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

前端之家收集整理的这篇文章主要介绍了C#是action.BeginInvoke(action.EndInvoke,null)一个好主意?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如果我想做一些“火和忘记”的一些代码,但还是要确保我的内存被清理(每 Why does asynchronous delegate method require calling EndInvoke?),以下是否会达到这个目标?
Action myAction = () => LongRunTime();
myAction.BeginInvoke(myAction.EndInvoke,null);

我已经环顾四周,但没有看到这种模式在任何地方使用.相反,人们使用annonomoyus方法作为其回调(例如The proper way to end a BeginInvoke?)或者它们定义了一个实际的回调方法.由于我还没有看到别人这样做,所以它让我觉得它不起作用,否则就是一个坏主意.

谢谢!

解决方法

使用方法组转换而不是委托是正确的,EndInvoke仍将在您的Action上被调用.没有别的事情要做,因为这是一场火灾,忘了电话.

不幸的是,由于Action是一个委托,我们不能在BCL的某个类中添加一个断点,所以直接无可辩驳地证明EndInvoke是非常有用的.

代码将(定期)检查由BeginInvoke返回的IAsyncResult的一些私有字段,这似乎跟踪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调用将使用仪器显示在Profilers上,但myAction.EndInvoke不会显示.

猜你在找的C#相关文章