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/
Related
I am trying to read value from control in worker thread.
public void worker()
{
while (true)
{
ewh.WaitOne();
int index = -1;
this.Invoke((MethodInvoker)delegate()
{
index = this.comboBoxSource.SelectedIndex;
});
// using index here
As I understand Invoke is launched asynchronously. Am I right that there is no guarantee at the point where I use index it Invoke will finish its work? If so, how can I make Invoke as blocking operation?
As I understand Invoke is launched asynchronously.
No, Invoke is synchronous, in that it will block until the delegate has completed in the UI thread. It's unfortunate that this isn't clearly documented in Control.Invoke(Delegate). The other overload (Control.Invoke(Delegate, object[]) states that it's the implementation of ISynchronizeInvoke.Invoke which is clearer:
Unlike BeginInvoke, this method operates synchronously, that is, it waits until the process completes before returning. Exceptions raised during the call are propagated back to the caller.
what is the purpose of running task synchronously
public static void RunMeSync()
{
for(int i = 0; i < 9999; i++)
{
ListBox1.Items.Add(i.ToString());
}
}
public static void Main()
{
Task T1 = new Task(()=>RunMeSync);
T1.RunSynchronously();
Task T2 = Task.Run(()=>RunMeSync);
}
is it pointless to do so ? what is the need to run task synchronously ?
Consider the following code snippet
public static void Main()
{
Task T1 = new Task(()=>RunMeSync);
T1.RunSynchronously();
RunMeSync();
}
is it the same thing running T1 Synchronously, invoking RunMeSync directly?
Is it the same thing running T1 Synchronously, invoking RunMeSync directly?
Yes, the effect is going to be the same. You would not gain anything by running synchronously a task constructed from a method that you could call directly.
However, not all tasks are like that: some are constructed from methods to which you have no access - for example, tasks passed into your class as parameters. In other cases a task would have no named method associated with it, because it is constructed from a lambda or with an anonymous delegate. In all these cases, RunSynchronously() provides a way to calling the logic that implements the task, without knowing or worrying about the way in which that logic has been defined.
A Task itself is just a unit of work - and as-such, is agnostic to how it is run.
It's entirely up to you to determine how it is run, based upon the needs, constraints and context of your program (albeit defaulting to potentially running in parallel)
The name RunSynchronously is a quite a bit of misnomer, better name would be TryToRunSynchronously. Method will wait for the task to complete anyway irrespective of which thread it ran, maybe that's why they picked up this name.
Yes, as the name suggests Task will not be always run synchronously in current thread. If the underlying scheduler refuses to inline, Task will still be queued for execution and wait for it to complete. TaskScheduler.TryExecuteTaskInline decides whether the Task is a candidate for inlining or not, another one parameter deciding the task inlining is the amount of stack available. So it is not same as calling the method synchronously.
It might be helpful when you're dealing with some very deep recursive algorithms. Very deep recursion can cause StackOverflowException, you can check whether you have enough stack to proceed the recursion, if not just execute the Task in another thread (In fact that's how it is implemented).
Consider we are parallelizing some work. We split the work across threads and each of them does some deep recursion, If you're doing this with traditional recursive function, you'll end up with StackOverflowException. But if you wrap the recursive method logic inside Task.RunSynchronously then it will automatically stop recursing and queue the task to the underlying Scheduler and wait for it to complete if there is not enough stack available.
Suppose I have a static method like so:
public static string ProcessMessage()
{
string testString = " this is test ";
....
return testString ;
}
and another method SendMessage:
public void SendMessage()
{
Thread th = new Thread(this.ProcessMessage);
th.Start();
th.Join();
}
What happens when SendMessage is called several times one right after another.
Suppose first thread calls ProcessMessage and is at line 1 and another thread calls ProcessMessage, what happens to the first thread? will it ever finish, since ProcessMessage is a static method? what will ProcessMessage properties look like? will thread 2 overwrite thread 1?
To answer your general question, multiple threads can call a static method, and each thread will process that method call separately. If static variables are used within the static method, then you may run into cross-threading issues, due to those variables being shared among multiple threads, but the method code itself is simply a set of instructions that will be followed by whatever threads enter it.
In regards to your specific example, the Thread Constructor can only be passed either a ParameterizedThreadStart or a ThreadStart object (and possibly an Int32). Both types of ThreadStart parameters are delegates with void signatures (they cannot return anything).
Also, since you are calling Thread.Start, followed by Thread.Join. Thread.Join blocks the calling thread until the waited on thread completes. Since that is the case, multiple calls to SendMessage() from the same thread will never spawn multiple simultaneous threads. Instead, each call will create a new thread and then wait for it to finish before moving on to the next call to SendMesage(). This is no better than simply calling ProcessMessage in the original thread.
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.
I came across a piece of C# code like this today:
lock(obj)
{
// perform various operations
...
// send a message via a queue but in the same process, Post(yourData, callback)
messagingBus.Post(data, () =>
{
// perform operation
...
if(condition == true)
{
// perform a long running, out of process operation
operation.Perform();
}
}
}
My question is this: can the callback function ever be invoked in such a way as to cause the lock(obj) to not be released before operation.Perform() is called? i.e., is there a way that the callback function can be invoked on the same thread that is holding the lock, and before that thread has released the lock?
EDIT: messagingBus.Post(...) can be assumed to be an insert on to a queue, that then returns immediately. The callback is invoked on some other thread, probably from the thread pool.
For the operation.Perform() you can read it as Thread.Sleep(10000) - just something that runs for a long time and doesn't share or mutate any state.
I'm going to guess.
Post in .net generally implies that the work will be done by another thread or at another time.
So yes, it's not only possible that the lock on obj will be released before Perform is called, it's fairly likely it will happen. However, it's not guaranteed. Perform may complete before the lock is released.
That doesn't mean it's a problem. The "perform various actions" part may need the lock. messagingBus may need the lock to queue the action. The work inside may not need the lock at all, in which case the code is thread safe.
This is all a guess because there's no notion of what work is being done, why it must be inside a lock, and what Post or perform does. So the code may be perfectly safe, or it may be horribly flawed.
Without know what messagingBus.Post is doing, you can't tell. If Post invokes the delegate it is given (the lambda expression in your example) then the lock will be in place while that lambda executes. If Post schedules that delegate for execution at a later time, then the lock will not be in place while the lambda executes. It's not clear what the the lock(obj) is for, to lock calls to messagingBus.Post, or what... Detailing the type (including full namespace) of the messagingBus variable would go a long way to providing better details.
If the callback executes asynchronously, then yes, the lock may still be held when Perform() unless Post() does something specific to avoid that case (which would be unusual).
If the callback was scheduled on the same thread as the call to Post() (e. g. in the extreme example where the thread pool has only 1 thread), a typical thread pool implementation would not execute the callback until the thread finishes it's current task, which in this case would require it releasing the lock before executing Perform().
It's impossible to answer your question without knowing how messagingBus.Post is implemented. Async APIs typically provide no guarantee that the callback will be executed truly concurrently. For example, .Net APM methods such as FileStream.BeginRead may decide to perform the operation synchronously, in wich case the callback will be executed on the same thread that called BeginRead. Returned IAsyncResult.CompletedSynchronously will be set to true in this case.