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.
Related
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.
A C#-method is calling on the main-thread after event raising. Then an another event is firing this same method during the first event is busy with the same method. So during debugging, I see in the calling stack two line in the same method on the same thread.
How can I hinder that the second event waits until the first event is ready with the same method. I'm trying with lock() but it doesn't block the same thread. AutoResetEvent can wait but will be waiting on the same thread.
Somebody has the tip? Thanks.
Your problem is caused by Application.DoEvents(). This method does have its uses but it is dangerous, you stumbled onto one of the reasons : re-entrant calls to events.
So, try
remove and avoid DoEvents().
or make all your eventhandlers capable of or resistant to re-entrancy. Take a critical look at what scenarios are possible with the close button for instance. A simple trick could be:
private bool busy = false;
private void MyHandler(sender s, EventArgs e)
{
if (busy)
return; // giving up, no queuing
busy = true;
// code
busy = false; // maybe in a finally clause
}
You can mark the method with MethodImplAttribute attribute.
Example:
[MethodImpl(MethodImplOptions.Synchronized)]
void Method()
{
....
}
Documentation (MSDN):
MethodImplOptions.Synchronized
Specifies that the method can be executed by only one thread at a time. Static methods lock on the type, whereas instance methods lock on the instance. Only one thread can execute in any of the instance functions, and only one thread can execute in any of a class's static functions.
Does Delegate.Invoke() start the method the delegate is pointed at on a new thread, or do you need to use Delegate.BeginInvoke() to do this?
Thanks
Delegate.Invoke: Executes synchronously, on the same thread.
Delegate.BeginInvoke: Executes asynchronously, on a threadpool thread.
from the answer here - What's the difference between Invoke() and BeginInvoke()
It runs on the same thread it is currently running, unless you do BeginInvoke
Delegate.Invoke() is just like calling the delegate, which will cause calling the delegate on the same thread. To make an async call on the delegate, you have to call it with BeginInvoke which eventually will make the call on a different thread (and then activate the Callback method)
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/