A question about Dispatcher.BeginInvoke
If I have a method as follows:
private void DoSomeWork()
{
MyCanvas.Dispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate
{
//Do something
return null;
}), null);
}
And I call the method multiple times, then the multiple calls are executed in the order they are created as per docs: If multiple BeginInvoke calls are made at the same DispatcherPriority, they will be executed in the order the calls were made. Dispatcher.BeginInvoke Method MSDN
How does one clear this to stop another call being made or to reset the queue to just a single call?
How does one clear this to stop another call being made or to reset the queue to just a single call?
You don't. You don't get to control the dispatcher queue. What you could do is keep a count of "pending requests" (making sure you update it atomically, of course) and only execute if this is the last call in the queue (i.e. when decrementing the count gives 0).
Another option would be to keep some sort of timer for when the last call was made, and ignore further calls within some period of time.
If you could give more details about what you're trying to achieve, we could give more concrete help.
The MSDN link that you provided gave you the answer with a little more digging.
This operation returns a DispatcherOperation object that can be used to cancel. But, that is on a per call basis, as you cannot control the queue in its entirety.
Related
I'm implementing the Threading concept in that we need to call more then one method simultaneous so for we used
Parallel.Invoke(
() => { GetLink(words); },
() => { GetSA(words); },
() => { Getlp(words); });
This case 1 working fine but. In case 2 we need to call three method and i need to find which method execute first and it has the result in the first method and other 2 method are need to kill or stop execute.it applicable for all the 3 method.
First, read this existing answer: C# Thread Termination and Thread.Abort()
Second, read this another one: What's wrong with using Thread.Abort()
General recommendation is 'never kill or abort a thread'. There are multiple reasons for this, however it is better to read detailed explanations on the web rather then re-post them here every time.
Instead of aborting/killing, modify your code so that sub-tasks can stop themselves gracefully.
You can have a shared CancellationToken (see CancellationTokenSource class), and check its status periodically in every thread's loop(s) - or use it in 'WaitAny' methods.
All threads will set this token at the time when they finish, so the first one to complete will send signal to others to stop.
If you don't have time or willingness to implement graceful stopping, create and run Threads explicitly, Parallel and Tasks are designed for a safer programming style.
On the Thread, you can call Abort method that will throw ThreadAbortException inside the Thread.
This is my requirement:
On a button click I need to get the data from database and populate in a datagridview, for which I'm using a function. As the retrieval may take a long time and I want to use the UI meanwhile, I want this function to run in a separate thread.
For this, I'm using async callback. But between the begininvoke() and endinvoke() function. I'm not writing any code (I don't know what to write to make the UI respond).
The datagridview is getting populated correctly but the UI is blocked when I'm trying to access it when the function is retrieving the data.
I'd recommend not to start the long running operation from the UI thread. Start another thread first, and then do the long running operation in that separate thread. When it is done, post the results back to the UI using the Form.Invoke() method. This way, the UI thread is not affected directly.
Instead of creating another thread by hand, you can also use a construct like BackgroundWorker.
If you do start the long running operation from the UI thread, you'd need to call Application.DoEvents() periodically (e.g. inside a loop). However, if the long running operation is an IO intensive -- meaning you are waiting for an IO operation most of the time -- then you won't get to call Application.DoEvents() as often as you'd like. This will make the UI seem less responsive or jerky. The seperate thread, as I mentioned above, is a better way in this regard.
If you are using a loop to Populate your DataGridView, You can use the Method Application.DoEvents() inside your loop to make your UI remain Responsive during the population of the DataGridView.
Update
As you stated the problem is not the loop, I think the best approach will be using the BackgroundWorker class.
Where you can populate the DataGridView in the DoWork() event of the BackgroundWorker
And you can start the BackgroundWorker.DoWork() event during the button_click event of your Code!
First of all, i should create asynccallback function in the UI form itself, not in middle level which is, in my case , DataMgr.
Also, i should add the last two parameters for begininvoke function with appropriate values where i have passed null values.
It should be
MethodDelegate dlgt = new MethodDelegate(DataMgr.countIssuingEntities);
TempValueHolder tmp = new TempValueHolder();
AsyncCallback cb = new AsyncCallback(MyAsyncCallBack);
IAsyncResult ar = dlgt.BeginInvoke(issueGroupId, element.ControlType, (EvaluatingEntityCombo.SelectedItem as CIQHydCore.RefData.RefDataInfo).Id, (IssuingEntityCombo.SelectedItem as CIQHydCore.RefData.RefDataInfo).Id, str1, str2,**cb,dlgt**);
and in MyAsyncCallBack function we need to populate the datgridview with the retrieved values from the end
Is there a way to assure the second statement executes after the first one?
DispatcherObjectInvoker.Invoke(_layouts,
() =>
_layouts.RaiseEvent(new LayoutEventArgs(
MainScreen.ChangedLayoutEvent,
this)));
DispatcherObjectInvoker.Invoke(_layouts, Grid.Refresh);
I'm accessing an Grid that is touched in the first statement. The refresh of the grid is working in about 80% of the cases only. I obviously have a race condition here.
Why not make them both part of the same action?
DispatcherObjectInvoker.Invoke(_layouts, () =>
{
_layouts.RaiseEvent(new LayoutEventArgs(MainScreen.ChangedLayoutEvent,
this));
Grid.Refresh();
});
Not sure what a DispatcherObjectInvoker is, but I will assume it's a wrapper for Dispatcher or something.
If it is, if you call Invoke(), it is a blocking call. So your second call is guaranteed to be after your first call.
However, if your intent is to have those be asynchronous calls, you should use BeginInvoke. The DispatcherPriority parameter helps ensure that calls made to the same priority level are in the same order. So, if _layouts refers to the DispatcherPriority.Loaded priority (or any other priority), the calls are guaranteed to be in the same order.
Check the MSDN documentation.
say we declare and run a thread in a method which has a while(1) loop. How can one avoid to create and run a second thread when the method is called again?
I only want one thread to start in this method and every time the method is called again, there should be no thread creation all over again. Should I check for the thread name or should I declare the thread as a field of the class?
Any ideas how to do this?
Thanks,
Juergen
It sounds like the thread should indeed be a field of the class - although you'll have to be careful to access it in a thread-safe way, if there could be several threads calling the method to start with.
What do you want to happen the second time - should the method block, or just finish immediately, or perhaps throw an exception? If you don't need to wait for the thread to finish, you might be able to get away with just a flag instead of keeping a reference to the thread itself.
(Note that I've been assuming this is an instance method and you want one extra thread per instance.) If that's not the case, you'll have to adjust accordingly.
Have the method return a singleton, and start the thread in the singleton constructor.
Could you save the synchronization context the first time, check on subsequent times to see if it matches, and post back to it if necessary?
SynchronizationContext syncContext = null;
...
// "object state" is required to be a callback for Post
public void HiThar(object state) {
if (syncContext == null) {
syncContext = SynchronizationContext.Current;
} else {
syncContext.Post(HiThar, state);
}
}
I have a multi-thread C# application that uses some recursive functions in a dll. The problem that I have is how to cleanly stop the recursive functions.
The recursive functions are used to traverse our SCADA system's hierarchical 'SCADA Object' data. Traversing the data takes a long time (10s of minutes) depending on the size of our system and what we need to do with the data.
When I start the work I create a background thread so the GUI stays responsive. Then the background worker handles the calling of the recursive function in the dll.
I can send a cancel request to the background worker using CancelAsync but the background worker can't check the CancellationPending flag because it is blocked waiting of the dll's recursive function to finish.
Typically there is only 1 recursive function active at a time but there are dozens of recursive functions that are used at various times by different background workers.
As a quick (and really shameful) hack I added a global 'CodeEnabled' flag to the dll. So when the GUI does the CancelAsync it also sets the 'CodeEnabled' flag to false. (I know I need some of those bad code offsets). Then the dll's recursive loop checks the 'CodeEnabled' flag and returns to the background worker which is finally able to stop.
I don't want to move the recursive logic to the background worker thread because I need it in other places (e.g. other background workers).
What other approach should be used for this type of problem?
It depends on the design, really. Much recursion can be replaced with (for example) a local stack (Stack<>) or queue (Queue<>), in which case a cancel flag can be held locally without too much pain. Another option is to use some kind of progress event that allows subscribers to set a cancel flag. A third option is to pass some kind of context class into the function(s), with a (volatile or synchronized) flag that can be set.
In any of these cases you should have relatively easy access to a cancel flag to exit the recursion.
FooContext ctx = new FooFontext();
BeginSomeRecursiveFunction(ctx);
...
ctx.Cancel = true; // or ctx.Cancel(), whatever
with (in your function that accepts the context):
if(ctx.Cancel) return; // or maybe throw something
// like an OperationCancelledException();
blah...
CallMyself(ctx); // and further down the rabbit hole we go...
Another interesting option is to use iterator blocks for your long function rather than regular code; then your calling code can simply stop iterating when it has had enough.
Well, it seems to me that you need to propagate the "stop now" state down the recursive calls. You could have some sort of cancellation token which you pass down the recursive calls, and also keep hold of in the UI thread. Something as simple as this:
public class CancellationToken
{
private volatile bool cancelled;
public bool IsCancelled { get { return cancelled; } }
public void Cancel() { cancelled = true; }
}
(I'm getting increasingly wary of volatility and lock-free coding; I would be tempted to use a lock here instead of a volatile variable, but I've kept it here for the sake of simplicity.)
So you'd create the cancellation token, pass it in, and then at the start of each recursive method call you'd have:
if (token.IsCancelled)
{
return null; // Or some other dummy value, or throw an exception
}
Then you'd just call Cancel() in the UI thread. Basically it's a just a way of sharing the state of "should this task continue".
The choice of whether to propagate a dummy return value back or throw an exception is an interesting one. In some ways this isn't exceptional - you must be partially expecting it, or you wouldn't pass the cancellation token in the first place - but at the same time exceptions have the behaviour you want in terms of unwinding the stack to somewhere that can recognise the cancellation easily.
I like the previous answers, but here's another.
I think you're asking how to have different cancel flag for different threads.
Assuming that the threads which you might want to cancel each have some kind of ThreadId then, instead of having a single global 'CodeEnabled' flag, you could have a global thread-safe dictionary of flags, where the TheadId values are used as the dictionary's keys.
A thread would then query the dictionary to see whether its flag has been set.