This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why does asynchronous delegate method require calling EndInvoke?
Is Delegate.EndInvoke() really necessary?
Working on a multi-threaded application at the moment and when raising an event instead of doing the normal handler.Invoke(); I am experimenting with handler.BeginInvoke();. Both work fine. However, for BeginInvoke I am using null for the last two arguments because there needs not be a callback and since there is no callback, there is definitely no need for data to be passed to a non-existent callback.
Because of this, I am not calling EndInvoke at all. But the application seems to.. work perfectly? I read and people said there would be leaks which may be occurring but I am just not noticing.
I'm curious though, what exactly does EndInvoke do? Do I really need to make a callback just to call EndInvoke and that's it? Also, why does EndInvoke take an IAsyncResult argument? I can just pass null for that right because there is no extra data being passed to the callback, correct? But still, I'm wondering, why, if there was extra data, would it need to be passed to EndInvoke? What is it doing with that parameter? I want to know how it works.
I checked the .NET Reflector but I couldn't find where EndInvoke was actually defined. In EventHandler (which is what I'm using) all it showed was the method header.
Thanks.
The main practical concerns are deterministically cleaning up a wait handle resource (if you chose to create the handle by referencing it) and making sure that Exceptions are propagated properly.
That said, what I would recommend is to move away from the slightly schizophrenic asynchronous pattern in the earlier .NET framework and use TPL, which has a much cleaner continuation model. The TPL even has some nice wrapping functionality to help deal with the older Begin/End style of calling:
http://msdn.microsoft.com/en-us/library/dd997423.aspx
As was mentioned in one of the referenced articles, if you're invoking a delegate in a fire-and-forget fashion, you probably should use ThreadPool.QueueUserWorkItem instead. Then you won't have to worry about cleaning up with EndInvoke.
According to MSDN, you ought to always call EndInvoke no matter what:
No matter which technique you use, always call EndInvoke to complete your asynchronous call.
So take that for what it's worth. I assume it's futureproofing.
Related
I am writing an application using asp.net core in which I need to create a new thread as I have an always running loop. At some point, I need to mill this thread. In asp.net, Thread.abort was the solution, but it is removed in asp.net core. What is the alternative solution for this?
Do not create your own thread for something like this!
There is a built-in method for using long running tasks in asp.core. You should read about this here.
You should create a class which derives from BackgroundService. Using this class is the easiest way to create a background-service that implements IHostedService. You can then add this to your program by calling services.AddHostedService<YourBackgroundService>() in the ConfigureServices method.
Note: In the page I linked, they use AddSingleton instead of AddHostedService. In .net core 2.1 and above you should use AddHostedService, not AddSingleton (there are some exceptions but we're talking in general here). See this answer for why that is.
If you implement your background-service like this, the shutdown of the additional thread will be handled for you. In your implementation of ExecuteAsync you need to just check if you should stop executing with the provided CancellationToken. You should also use asnyc implementations where possible and provide the CancellationToken there as well so the thread can end gracefully. You will never need to call Thread.Abort or even have access to the Thread itself; it's all done in the background for you.
Since this is not a direct answer to the question you asked but more of a correction of what you're probably doing wrong to get into this situation in the first place, I first wanted to make this a comment. However it's just too long and there are too many things to mention that's why I made this into an answer.
Hope this helps.
The cleanest way to do this via a flag that is set by the "killing" thread and checked periodically by the thread that needs to be killed. Thread.Abort() is not a reliable way to do it; even the MSDN says Calling this method usually terminates the thread.
Hi I've been thinking for some time that Subject<T> disposes all the subscriptions based on it if you manually call its Dispose method. But I've recently found it doesn't work that way, it just clears its inner collection of observers and substitutes it with a DisposedObserver helper class instance.
I found myself a little confused about the behaviour, just assumed that the "normal" would be just propagate and dispose all the suscribers. Later, trying to figure out why is designed this way, I guessed a couple of reasons why they designed this way.
The suscriber may be a composition that depents partially on the subject , so full propagation of disposal doesn't make sense. ie. Merge is not disposed just because one of the sources was disposed, as everyone expects.
Subject.Dispose It is semantically equivalent to a continuation with Observable.Never from the side of the observer. The Subject.Dispose caller can also call OnComplete or OnError if wanted to signal error or completion before disposal (because they are on the same scope).
Edit Note:
Sorry for the unclear question. I already understand how to use it, this was more a design question. Let me state it more clearly.
Why do you think the designers of Rx made Dispose behaviour that way?
(the two points above are my answer trial)
A subject should indicate it is done by sending OnComplete or possibly OnError. This is idiomatically and grammatically correct Rx. Subscribers are responsible for ending their subscriptions by disposing them. You should write Observables such that they clean up resources once they are "done" even if subscribers have not unsubscribed.
This msdn article is entitled "How to call a Visual C# method asynchronously".
The article says "Asynchronous calls are made by using delegates" to which I reply in my head "not necessarily, that's only one way to do it".
The matter-of-fact tone of the articles statement makes me wonder - Is it a best practice, or does MS consider it a best practice, to use delegates when making asynchronous calls?
Up to the current .NET version, asynchronous methods have typically been handled in separate background threads from the one you trigger them from, so it's been mostly essential to do it using a delegate that you can invoke in another thread.
However, with the recent C# Async CTP (which will probably be in C# 5.0 or another future version), the story is changed a little - it's not essential to use delegates, you can write code in a traditional imperative style, and the compiler will do most of the work for you. This might involve delegates, but not necessarily - the compiler does some clever tricks and writes a finite state machine which can be used to execute code asynchronously.
Yes, delegates are the way to call methods asynchronously. It is not best practice, that is how it is done. In .NET, you must use a delegate.
Somebody can tell me im wrong please but i've been under the impression at compile time a delegate is as good as a method, the purpose of a delegate being a signature definition. I can think of no other way of executing async code without a method even if its anonymous which becomes a method at compile time..
I was told that Invoke() is similar to normal method calling... so why would people choose to use Invoke and not normal method calling?
I tried to search online regarding the issue, what i get is the advantages of using BeginInvoke(), but what are the advantages of using Invoke()?
Use BeginInvoke when you want to call the delegate asynchronously (on a thread drawn from the thread pool) and Invoke if you want to call it synchronously.
It's worth noting first that we have to have something like .Invoke() as the meeting-point between languages. Just as what is int to C# and Integer to VB.NET is System.Int32 to both of them, and to any other CLR language; so too we have Invoke() which any CLR language can offer access to, and which they can then provide additional syntactic sugar in a means suitable for their syntax (most would consider heavily VB style conventions in C# or heavily C# style conventions in VB to be syntactic vinegar; sugar always has to match the rest of the language as best it can).
This sugar added, why not use it all the time? Some people will sometimes want to be clear that they are dealing with a delegate. Some just won't use it; I mostly don't. Like all syntactic sugar, the advantages and disadvantages are matters of clarity rather than correctness (indeed, look at a call to x.Invoke() in reflector and you'll see that it as x() because reflector doesn't know which you used).
One reason is if you've gotten your method signature through reflection and you dynamically want to instantiate a function, Invoke() is the way you'd do that.
In order to change, for example, the thread executing something.
Note that any UI control shall and can alweays only be manipulated from the thread that created it (message pump, actually). So, if another thread is manipulating the control (synchronously from that other threads point of view) then BeginInvoke would be additional overhead, but Invoke is fine (ESPECIALLY because at least in WPF there is a shortcut herere for multiple invoke sequences that make it faster to execute internally).
I guess you already understand what a delegate is, what is for, and why is useful.
If I have a deletegate named "MyDelegate", I can do "MyDelegate(foo);" or "MyDelegate.Invoke(foo);" , but I always use the second one so I could easily see when I review the code, that is actually a delegate and not a method. There is no internal difference.
I've read conflicting opinions as to whether every BeginInvoke() has to be matched by an EndInvoke(). Are there any leaks or other problems associated with NOT calling EndInvoke()?
Delegate.EndInvoke is documented as a thou shalt call this (i.e. necessary - else leaks happen) - from msdn:
Important Note
No matter which technique you use,
always call EndInvoke to complete your
asynchronous call.
Control.EndInvoke is OK to ignore for fire-and-forget methods - from msdn:
You can call EndInvoke to retrieve the
return value from the delegate, if
neccesary, but this is not required.
However - if you are using Delegate.BeginInvoke and don't want the result, consider using ThreadPool.QueueUserWorkItem instead - it'll make life a lot easier, and avoid the pain of IAsyncResult etc.
EndInvoke is not optional.
More info here
And EndInvoke call is not optional call, it is a part of the contract. If you call BeginInvoke you must call EndInvoke.
Classic example of why this is necessary. It's very possible that the IAsyncResult returned from BeginInvoke has allocated resources attached to it. Most commonly a WaitHandle of sorts. Because IAsyncResult does not implement IDisposable another place must be chosen to free the resources. The only place to do so is EndInvoke.
I briefly discuss this problem in the following blog post.
http://blogs.msdn.com/jaredpar/archive/2008/01/07/isynchronizeinvoke-now.aspx
EndInvoke is not optional because it is the place where exceptions are thrown if something went wrong in the asyncronous processing.
Anyway there should not be any leak because if the IAsyncResult is holding some native resource it should correctly implement IDisposable and dispose such resources when the GC calls his finalizer.
It is not optional because calling BeginInvoke makes use of a WaitHandle which in turns makes use of a kernel object that maintains a count for how many references are had to it. Calling EndInvoke gracefully disposes the handle which decrements that counter on the kernel object and when that count reaches zero, the kernel object manager will destroy it.
Its only optional if you don't mind your program's memory growing very large. The issue is that the GC is holding onto all of the references in your thread, because you might want to call EndInvoke at some point. I would go with Marc's answer, the threadpool will make your life easier. However, you need to watch out if you spawn threads from your threads, as it is limited in the number of threads it can spin up.
Every reply on this post says that EndInvoke() is not optional. However, I found the following highly ranked comment that is the accepted answer on this SO thread:
"Note that the Windows Forms team has guaranteed that you can use Control.BeginInvoke in a 'fire and forget' manner - i.e. without ever calling EndInvoke. This is not true of async calls in general: normally every BeginXXX should have a corresponding EndXXX call, usually in the callback."
What's the difference between Invoke() and BeginInvoke()