0

Heres the hypothetical example:

WebCleint wc = new WebClient();

wc.DownloadStringCompleted += wc_DownloadStringCompleted;

wc.DownloadStringAsync(new Uri(callString));

wc = new WebClient();

wc.DownloadStringCompleted += wc_DownloadStringCompleted;

wc.DownloadStringAsync(new Uri(callString));

From my understanding the garbage collector wont grab something until its completly dereferenced. So I guess my REAL question is, does a event registration count as a reference to an object?

Can I make this call and have both returns come back through the same completed method?

I have many different web calls that could be made. They all need to be done async. They can all happen at random times.

Right now I just kinda assume that the way I have it built prevents concurrent calls however thats a bad way to build stuff haha.

I am attempting to avoid creating a stack queue.

Nick
  • 1,417
  • 1
  • 14
  • 21
DotNetRussell
  • 9,716
  • 10
  • 56
  • 111
  • I think he means a queue-handler for downloading strings and keep track of every download into a queue. – Jeroen van Langen Aug 11 '13 at 00:11
  • Yeah I just mean I would check if the WebClient is busy. If it is then stick the call on a stack. When the clients done, pop it off and run it. Which in itself is an easy solution. However the return types need to be handled VERY differently so it would be a ton of custom code for each one. – DotNetRussell Aug 11 '13 at 00:16
  • @AMR why do you want to use the same WebClient? Just create a one, download something and dispose it. What is wrong with that? You may also use Tasks/Threads with create its own WebClients. – I4V Aug 11 '13 at 00:20
  • @I4V its complicated... lol Id rather not get into the application but there is good reason why its structured this way. I just want to stop fringe cases of concurrent calls. – DotNetRussell Aug 11 '13 at 00:21
  • @AMR OK, but I really want to hear `the good reason why its structured this way` – I4V Aug 11 '13 at 00:28
  • @I4V Not the above way just to be clear. That was just a hypothetical. – DotNetRussell Aug 11 '13 at 00:33

2 Answers2

1

Every event registration will keep the object (WebClient) alive, unless you current instance (the instance containing the wc_DownloadStringCompleted) is released. You could deregister the event in wc_DownloadStringCompleted. To get the original WebClient in the wc_DownloadStringCompleted, use the sender object.

public void wc_DownloadStringCompleted(object sender, EventArgs e)
{
    WebClient  wc = (WebClient)sender;

    wc.DownloadStringCompleted -= wc_DownloadStringCompleted;

    // handle download completed
}
Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
  • In this case, wc is the event publisher. No matter how many event handlers are registered against wc's events, it is wc that holds the reference to the subscribers. – Patrick Hallisey Aug 11 '13 at 00:16
  • 1
    That's right, wc holds the reference. The GC doesn't care how many references an object holds, just how many references to the object are held. – Patrick Hallisey Aug 11 '13 at 00:20
1

Similar to this question:

Do event handlers stop garbage collection from occurring?

It would appear that publishers, wc in this case, don't have their garbage collection affected. wc holds a reference to the event handler, but nothing holds a reference to wc.

Community
  • 1
  • 1
Patrick Hallisey
  • 888
  • 6
  • 11
  • So I am not afraid to say that was a great answer but a little over my head. Is he saying that if your publisher (wc in this case) is holding a reference to an event handler that it will execute it once then get collected? – DotNetRussell Aug 11 '13 at 00:29
  • There is nothing preventing wc from being collected before the event is fired except for the internals of WebClient. If DownloadStringAsync creates an internal reference to the webclient, then it may stay alive long enough to fire the event. – Patrick Hallisey Aug 11 '13 at 00:49
  • So when you say MAY stay alive does that mean that there is a chance that it will maintain a reference and still be disposed? – DotNetRussell Aug 11 '13 at 00:51
  • 1
    There are many references made to the WebClient internally by the Download{Action}Async methods, but these references fall in the realm of undocumented implementation. From what I can tell, the fairly complex internalls of the async request methods on WebClients will hold references to the WebClient. If you create a WebClient and make an async call, it should keep itself alive through its own internal objects and references. But that's relying on the internal implementation of a framework class to always have the same side effects. – Patrick Hallisey Aug 11 '13 at 01:41