Could you explain this for me please:
someformobj.BeginInvoke((Action)(() =>
{
someformobj.listBox1.SelectedIndex = 0;
}));
Could you tell me how can I use begininvoke exactly?
What is Action type?
Why there is blank brackets ()?
And what does this mean =>?
Action is a Type of Delegate provided by the .NET framework. The Action points to a method with no parameters and does not return a value.
() => is lambda expression syntax. Lambda expressions are not of Type Delegate. Invoke requires Delegate so Action can be used to wrap the lambda expression and provide the expected Type to Invoke()
Invoke causes said Action to execute on the thread that created the Control's window handle. Changing threads is often necessary to avoid Exceptions. For example, if one tries to set the Rtf property on a RichTextBox when an Invoke is necessary, without first calling Invoke, then a Cross-thread operation not valid exception will be thrown. Check Control.InvokeRequired before calling Invoke.
BeginInvoke is the Asynchronous version of Invoke. Asynchronous means the thread will not block the caller as opposed to a synchronous call which is blocking.
I guess your code relates to Windows Forms.
You call BeginInvoke if you need something to be executed asynchronously in the UI thread: change control's properties in most of the cases.
Roughly speaking this is accomplished be passing the delegate to some procedure which is being periodically executed. (message loop processing and the stuff like that)
If BeginInvoke is called for Delegate type the delegate is just invoked asynchronously.
(Invoke for the sync version.)
If you want more universal code which works perfectly for WPF and WinForms you can consider Task Parallel Library and running the Task with the according context. (TaskScheduler.FromCurrentSynchronizationContext())
And to add a little to already said by others:
Lambdas can be treated either as anonymous methods or expressions.
And that is why you cannot just use var with lambdas: compiler needs a hint.
UPDATE:
this requires .Net v4.0 and higher
// This line must be called in UI thread to get correct scheduler
var scheduler = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext();
// this can be called anywhere
var task = new System.Threading.Tasks.Task( () => someformobj.listBox1.SelectedIndex = 0);
// also can be called anywhere. Task will be scheduled for execution.
// And *IF I'm not mistaken* can be (or even will be executed synchronously)
// if this call is made from GUI thread. (to be checked)
task.Start(scheduler);
If you started the task from other thread and need to wait for its completition task.Wait() will block calling thread till the end of the task.
Read more about tasks here.
Related
In Async/Await FAQ, Stephen Toub says:
An awaitable is any type that exposes a GetAwaiter method which returns a valid awaiter.
...
An awaiter is any type returned from an awaitable’s GetAwaiter method and that conforms to a particular pattern.
So in order to be an awaiter, a type should:
Implement the INotifyCompletion interface.
Provide a boolean property called IsCompleted.
Provide a parameterless GetResult method that returns void or TResult.
(I'm ignoring ICriticalNotifyCompletion for now.)
I know the page I mentioned has a sample that shows how the compiler translates await operations but I'm stil having a hard time understanding.
When I await an awaitable,
When is IsCompleted checked? Where should I set it?
When is OnCompleted called?
Which thread calls OnCompleted?
I saw examples of both directly invoking the continuation parameter of OnCompleted and using Task.Run(continuation) in different examples, which should I go for and why?
Why would you want a custom awaiter?
You can see the compiler's interpretation of await here. Essentially:
var temp = e.GetAwaiter();
if (!temp.IsCompleted)
{
SAVE_STATE()
temp.OnCompleted(&cont);
return;
cont:
RESTORE_STATE()
}
var i = temp.GetResult();
Edit from comments: OnCompleted should schedule its argument as a continuation of the asynchronous operation.
In the vast majority of cases, you as a developer need not worry about this. Use the async and await keywords and the compiler and runtime handle all this for you.
To answer your questions:
When does the code checks IsCompleted? Where should I set it?
The task should set IsCompleted when the task has finished doing what it was doing. For example, if the task was loading data from a file, IsCompleted should return true when the data is loaded and the caller can access it.
When does it calls OnCompleted?
OnCompleted usually contains a delegate supplied by the caller to execute when the task has completed.
Does it call OnCompleted in parallel or should the code
inside OnCompleted be asynchronous?
The code in OnCompleted should be thread neutral (not care which thread it is called from). This may be problematic for updating COM objects in Single Threaded Apartments (like any UI classes in Metro/Windows8/Windows Store apps). It does not have to be asynchronous but may contain asynchronous code.
I saw examples of both directly invoking the continuation parameter of OnCompleted
and using Task.Run(continuation) in different examples, which should I go for and when?
Use async/await when you can. Otherwise, use Task.Run() or Task.Wait() because they follow the sequential programming model most people are used to. Using continuations may still be required, particularly in Metro apps where you have apartment issues.
I wonder if the following code buys any performance gains:
if (Deployment.Current.Dispatcher.CheckAccess())
{
DoUIWork();
}
else
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
DoUIWork());
}
Is the Dispatcher smart enough to short circuit a dispatch to the UI thread if its unnecessary?
I couldn't say whether the dispatcher does anything expensive when dispatching from the UI thread to itself, compared with the check. But BeginInvoke from the UI thread may behave differently from executing the operation directly, as it's at least put on the queue rather than invoked immediately. You could tell the difference between this and removing the conditional statement if you had code directly afterwards.
Certainly worth being aware of the control flow, enough to know if the difference doesn't matter.
If it is anything like standard Windows SynchronizationContext (and it probably is) then the two options are not the same. BeginInvoke will basicaly queue up the method to be executed by the dispatcher message pump after the current execution of any existing message has been processed.
In your example the two options be the same if you were to use Invoke instead of BeginInvoke.
I was using code like this:
handler.Invoke(sender, e);
But the problem with that code is that it is synchronous and all it really does is update the GUI. It is not necessary for the server to wait for it to complete so it should be made asynchronous.
I don't really want to use BeginInvoke and EndInvoke because a callback method is not necessary in this case.
Is this a suitable alternative?
Task.Factory.StartNew(() => handler.Invoke(sender, e));
The way you did it is fine, another way to do this that works on .NET 3.5 is using the ThreadPool class instead
ThreadPool.QueueUserWorkItem(new WaitCallback((a) => handler.Invoke(sender, e)))
Also if handler happens to be a derived from control, you are allowed to call BeginInvoke without a corresponding EndInvoke.
Calls to GUI are special in that they must always be done from the GUI thread. In your own words, handler.Invoke(sender, e) "updates the GUI", yet it is (probably) not executed from the GUI thread, so it not OK in its current form.
In WinForms, you'll need to wrap your task delegate into Control.Invoke (or forget about tasks and just use Control.BeginInvoke).
If WPF, you can wrap your task delegate into Dispatcher.Invoke (or just use Dispatcher.BeginInvoke without a task).
I'm not familiar with C# 4's Task class, but I know BeginInvoke works just fine without EndInvoke. I sometimes write code like this:
handler.BeginInvoke(sender, e, null, null);
Edit: I was mistaken. While EndInvoke is not necessary to cause the code to execute on a new thread, the documentation clearly states that EndInvoke is important.
Is it good practice to invoke delegate for MainForm thread - this way?:
Txt.MainForm.EndInvoke(
Txt.MainForm.BeginInvoke(
new MethodInvoker(delegate()
{ // code here }
)));
No - because if you're calling EndInvoke, that will block until the delegate has completed. If you want that behaviour, just use Invoke instead.
To put it another way: if you're trying to do something other than blocking until your (presumably UI-modifying) delegate has executed in the UI thread, you should explain what that something is. If there isn't anything else, then Invoke will give you simpler code.
It doesn't make a lot of sense as the code fires up an asynchronous call and then immediately waits for the call to finish. I.e. you end up waiting on the calling thread.
Not considering the thing that other mentioned (I believe this EndInvoke - BeginInvoke chain is just an example usage of delegate): Using delegates is 100% OK. If this is the only usage of the delegate body, there's no need to define it as a named method. It is cleaner in the code and there's no need to jump through the file. Consider using newer syntax for delegates:
new MethodInvoker(() => { // code here })
I have some doubts on executing the following :
public class Test
{
delegate int TestDelegate(string parameter);
static void Main()
{
TestDelegate d = new TestDelegate(PrintOut);
d.BeginInvoke("Hello", new AsyncCallback(Callback), d);
// Give the callback time to execute - otherwise the app
// may terminate before it is called
Thread.Sleep(1000);
Console.ReadKey(true);
}
static int PrintOut(string parameter)
{
Console.WriteLine(parameter);
return 5;
}
static void Callback(IAsyncResult ar)
{
TestDelegate d = (TestDelegate)ar.AsyncState;
Console.WriteLine("Delegate returned {0}", d.EndInvoke(ar));
}
}
1 ) The TestDelegate already pointing to a Method ( "PrintOut").Why do Again we are passing another method ("callback") in d.BeginInvoke("Hello",new AysncCallback(Callback),d);.Does it mean d.BeginInvoke executes "PrintOut" and "Callback" parallely?.Can you please explain line by line what exactly going on?
2) Normally, Aysnchronous execution means the execution of a "thread" is not predictable
or fastest execution ?
3) TestDelegate d = (TestDelegate)ar.AsyncState;
"TestDelegate" d is a delegate.How is it possible to cast it to filed or property? ( ar.AsyncState )
4) can you provide me some live example where do i need to use this Asynchronous execution?
1 ) The TestDelegate already pointing to a Method ( "PrintOut").Why do Again we are passing another method ("callback") in d.BeginInvoke("Hello",new AysncCallback(Callback),d);.Does it mean d.BeginInvoke executes "PrintOut" and "Callback" parallely?.Can you please explain line by line what exactly going on?
PrintOut and Callback are not executed in paralled. Callback will be called when PrintOut has finished and returned.
2) Normally, Aysnchronous execution means the execution of a "thread" is not predictable or fastest execution ?
No. Asynchronous execution means the execution is not synchronous. That is.. the timing and execution time of the execution are not related to the timing of the piece of code that starts the asynchronous operation. It is the opposite of synchronous execution. With synchronous operation you would expect the execution to complete before the next statement is executed. For example, calling another method directly is synchronous operation, or another example is calling a function on a remote service and waiting for it to return before continuing.
3) TestDelegate d = (TestDelegate)ar.AsyncState; "TestDelegate" d is a delegate.How is it possible to cast it to filed or property? ( ar.AsyncState )
The delegate is not being case to a field or property. The cast is the other way around. The field or property is being cast into a TestDelegate.
4) can you provide me some live example where do i need to use this Asynchronous execution?
An example might be if you have a user interface that displays reports. The report might need to be generated from data in a database and takes a long time to generate. You would want to generate the report asynchronously so that the user interface can carry on running. If the report was not generated asynchronously the user interface might appear to be frozen and the user might think the program has crashed.
PrintOut is the function that will be executed on a thread from the thread pool and is the function your delegate is pointing to. Callback is the function that will be executed once PrintOut finishes and in which you have to call the EndXXX method which will give you the result of the PrintOut execution. These two functions are not executed in parallel. Here's line by line:
Create a delegate pointing to the PrintOut method
Draw a thread from the thread pool (if available) and run the PrintOut method on this thread by passing "Hello" as argument.
In the meantime the main thread sleeps for 1 second
Once the PrintOut method finishes executing, the Callback method is called. This is where you handle the result of the asynchronous operation.
As far as the casting is concerned: AsyncState is an object, a delegate in .NET is also an object, so no problem casting.
1) Callback will be called by the runtime after PrintOut is executed.
2) Yes, it is not predictable. BeginInvoke makes code to execute on thread from pool, so real performance depends on many parameters, such as thread usage in other places of your program.
3) Delegates are objects. So, reference to them can be casted to object and backward. In case of IAsyncResult returned by BeginInvoke, AsyncState stores delegate, to make proper result extraction possbile.
4) A fragment from a program opening turnstile and making indication (both are time consuming) after user authentication:
if(user.Id.HasValue)
{
Action openDoor = turnstile.Open;
Action<LedColor> indicate = led.SetColor;
// starting async operations
openDoor.BeginInvoke(openDoor.EndInvoke, null);
indicate.BeginInvoke(LedColor.Green, indicate.EndInvoke, null);
// main thread activity.
MakeRecordToLog();
}
1) The callback gets called after your work (PrintOut) has finished. You can pass also a null value.
2) Aysnchronous execution means that your code runs on another thread than the main thread of the application.
3) ar.AsyncState is set to the value you passed in the 3rd parameter of the BeginInvoke method.
4) Check out this: http://shiman.wordpress.com/2008/09/10/c-net-delegates-asynchronous-invocation-begininvoke-method/