事件触发前对象处理和垃圾收集 [英] Object disposal and garbage collection prior to event triggering

查看:142
本文介绍了事件触发前对象处理和垃圾收集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  private void DownloadInformation(string id)
{
using(WebClient wc = new WebClient())
{
wc.DownloadStringCompleted + =
new DownloadStringCompletedEventHandler(DownloadStringCompleted);
wc.DownloadStringAsync(new Uri(http://www.fake.com/+ id));
}
}

以上是一个简化版本: p>



(我有作者的许可发布图片。)



令人困扰的是,该代码附加了一个事件处理程序, DownloadStringAsync()被调用,然后使用块的结束,调用 Dispose() Web客户端。有没有什么可以防止 WebClient 使用排除,甚至在 DownloadStringAsync() complete和 DownloadStringCompleted 事件触发?



有一种较新的方法, DownloadStringTaskAsync(),我认为与 await 一起使用:

  private async任务DownloadInformation(string id)
{
using(WebClient wc = new WebClient())
{
wc.DownloadStringCompleted + = DownloadStringCompleted;
await wc.DownloadStringTaskAsync(new Uri(http://www.fake.com/+ id));
}
}

然而,即使这样...我基本上会在 WebClient 被放弃之前,会触发事件触发器和处理程序。



我误解了 WebClient 在这种情况下或这是一个可怕的代码设计?

解决方案

WebClient不实现IDisposable,它的基类Component。



组件类处理已注册到其Events属性但WebClient不使用该属性的任何事件处理程序。



内部资源的实际处理是在私有方法中完成的

在WebClient上调用处理对webclient管理的任何状态都没有影响。 code> DownloadBits 和内部类 DownloadBitsState



所以您显示的代码由于过早发布资源而无任何影响。然而,这是由实现细节引起的。这些可能会在将来发生变化。



由于框架跟踪待处理的回调,您不必担心过早的垃圾回收,一个href =https://stackoverflow.com/a/1279746/578411>这个答案,由Alexei Levenkov提供。


A piece of code was brought up by someone I was talking to:

private void DownloadInformation(string id)
{
    using (WebClient wc = new WebClient())
    {
        wc.DownloadStringCompleted += 
            new DownloadStringCompletedEventHandler(DownloadStringCompleted);
        wc.DownloadStringAsync(new Uri("http://www.fake.com/" + id));
    }
}

The above is a simplified version of this:

(I have the author's permission to post the image.)

What bothers me about that code is that an event handler is attached, DownloadStringAsync() is called and then the using block ends, which calls Dispose() on WebClient. Is there anything that will prevent WebClient from being disposed off by using and even garbage collected prior to DownloadStringAsync() completing and DownloadStringCompleted event triggering?

There's a newer method, DownloadStringTaskAsync(), which I would think to use in conjunction with await:

private async Task DownloadInformation(string id)
{
    using (WebClient wc = new WebClient())
    {
        wc.DownloadStringCompleted += DownloadStringCompleted;
        await wc.DownloadStringTaskAsync(new Uri("http://www.fake.com/" + id));
    }
}

However, even then... I would basically be betting that event triggers and handler gets called before the WebClient gets disposed off.

Am I misunderstanding the life cycle of WebClient in this scenario or is this a terrible code design?

解决方案

The WebClient doesn't implement IDisposable, its base class Component does.

The Component class Disposes any eventhandlers that are registered with its Events property but the WebClient doesn't use that property.

Calling Dispose on the WebClient doesn't have an effect on any state managed by the webclient.

The actual handling of internal resources is done in the private method DownloadBits and an internal class DownloadBitsState.

So the code you show is up to now free of any effects due to releasing resources too early. That is however caused by an implementation detail. Those might change in the future.

Due to the framework keeping track of pending callbacks you don't have to worry about premature garbage collection as well, as is explained in this answer, kindly provided by Alexei Levenkov.

这篇关于事件触发前对象处理和垃圾收集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆