AgrumenNullException in ThreadPool.QueueUserWorkItem - c#

I've got a method which gets called frequently by different treads. Sometimes I get an AgrumenNullException when ThreadPool.QueueUserWorkItem(display(angebot), null); gets called, stating that the parameter callBack (the first parameter) is null.
What am I doing wrong?
public class ai : UserControl
{
//...
public void Display(Angebote angebot)
{
lock (_syncObj) { _current = angebot; }
ThreadPool.QueueUserWorkItem(display(angebot), null);
}
private WaitCallback display(Angebote angebot)
{
// doing something
}
//...
}

The ThreadPool.QueueUserWorkItem will do the work as defined in the WaitCallback delegate returned by display(Angebote). I would surmise that your display method sometimes returns null.
Is your intent to execute display(angebot) in the background thread, or does that method discern what method should be executed?
If you're thinking that your display method should be executing in a background thread:
private WaitCallback display(Angebote angebot)
{
// doing something in a background thread
}
Then your code should look like:
ThreadPool.QueueUserWorkItem(display, angebot);
private void display(object state)
{
Angebot angebot = (Angebot)state;
// doing something in a background thread
}
EDIT: If it's the latter where display is figuring out what background thread to execute, then perhaps you have something looking like this:
private WaitCallback display(Angebote angebot)
{
if (angebot.Something)
{
return new WaitCallback(BackgroundTask1);
}
else
{
return null;
}
}
But since you haven't posted that code, I'm not sure. In this case, returning null is invalid for ThreadPool.QueueUserWorkItem.

Related

Can I create a C# async method without using a different thread (Task)?

I have searched a lot and it seems C# async await has to be used together with Task.
The situation is that I have a method that is very time consuming which is OK, but I hope it won't block the main method.
So I describe the main method as "async", and inside it, I call and "await" the time consuming method, but C# need the time consuming method to be included in a Task which means it will be executed in a seperate thread. But that method has something that cannot run outside main thread.
And my question is how can I run the time consuming method asynchronously without putting it in a different thread?
Thank you very much.
PS: I'm doing this in Unity3D, is it possible to leverage Coroutine to reach the goal?
//main method
private async void MainMethod()
{
//...
bool result = await TimeConsumingMethod();
//...
}
//time consuming method
private async Task<bool> TimeConsumingMethod()
{
bool result;
await Task.Run(()=>
{
//...
//SOME CODE THAT CANNOT run in thread other than main
//...
});
return result;
}
To run anything aysnchronously (not blocking the main thread) in unity you have to use a different Thread/Task.
But as you also want to run code on the main thread in that separate thread you'll have to communicate between the two.
Although you can't run anything on the main thread from inside a different thread. You can make a queue that the main thread consistently handles. When the off thread then wants to do something on the main thread it adds it to the queue and the mainThreadHandler will then handle it in the next frame update. So the off thread can then tell the main thread that it wants to do something on the main thread and wait for the main thread to be done with that code and then continue with the processing after.
This is an implementation of a main thread handler:
public class MainThreadHandler:MonoBehaviour
{
private static readonly Queue<Action> _executionQueue = new Queue<Action>();
public void Update()
{
lock (_executionQueue)
{
while (_executionQueue.Count > 0)
{
_executionQueue.Dequeue().Invoke();
}
}
}
public static void Enqueue(Action action)
{
lock (_executionQueue)
{
_executionQueue.Enqueue(action);
}
}
}
Calling your code including calling things in the main thread and then waiting for it will then look something like this:
private Task currentTask;
private bool taskResult;
public void StartOffThreadMethod()
{
currentTask = Task.Run(() =>
{
DoCalculationsOffThread();
bool isMainThreadDone = false;
MainThreadHandler.Enqueue(() =>
{
//Main thread code
//Either set a bool that the off thread checks to see if the action has been completed
//or start a new task that handles the rest of the off threaded code
//This example uses a isDone bool
isMainThreadDone = true;
});
while (!isMainThreadDone)
{
Thread.Sleep(100);
}
DoOtherCalculationsOffThread();
taskResult = true;
});
}
private void Update()
{
if (currentTask != null && currentTask.IsCompleted)
{
//do stuff with the result
}
}
I'd also like to add that going back and forth between the main thread and an calculating thread can be rather tricky business. If it can be prevented i would try to prevent it.

How do I wait for the result from Dispatcher Invoke?

I think I'm missing something here. I've got a WPF form that has some methods on it I need to call from an external source (usually on a non-UI thread). I retrieve a reference to the form, then attempt to call the method via Dispatcher.Invoke so it's marshalled to the UI thread. The problem is that this code won't work as the Invoke fires an Action, so the result is always an empty string (even though the docs say Invoke is supposed to be synchronous).
public string GetValueById(string id, string value)
{
Application.Current.Dispatcher.Invoke(() =>
{
var main = Application.Current.MainWindow as MainWindow;
if (main != null)
{
return main.GetValue(id);
}
});
return "";
}
I can't quite wrap my head around how to make this work.
If you look at the documentation for that Dispatcher.Invoke overload, you'll see that if you pass it a Func<TResult> callback then it will return the TResult returned by executing that callback. All you have to do is actually make use the return value:
public string GetValueById(string id, string value)
{
return Application.Current.Dispatcher.Invoke(() =>
{
var main = Application.Current.MainWindow as MainWindow;
if (main != null)
{
return main.GetValue(id);
}
});
}

ManualResetEvent WaitOne blocks the owner Thread of my CollectionView

I've written a WPF WizardFramework which performs some actions in the background using some BackgroundWorker. While processing it can happen that I have to update an ObservableCollection which is bound to my UI.
For this case I've written a ThreadableObservableCollection, which provides threadsafe methods for Insert, Remove and RemoveAt. Though I'm using .NET 4.5 I was not able to get BindingOperations.EnableCollectionSynchronization working without many other invalid access exceptions. My Collection looks like:
public class ThreadableObservableCollection<T> : ObservableCollection<T>
{
private readonly Dispatcher _dispatcher;
public ThreadableObservableCollection()
{
_dispatcher = Dispatcher.CurrentDispatcher;
}
public void ThreadsafeInsert(int pos, T item, Action callback)
{
if (_dispatcher.CheckAccess())
{
Insert(pos, item);
callback();
}
else
{
_dispatcher.Invoke(() =>
{
Insert(pos, item);
callback();
});
}
}
[..]
}
This is working as expected, while I am using the wizard in my application. Now I'm using NUnit to write some integrationtests for the application.
There's a listener which waits for the WizardViewModel to finish it's work and looking for some pages which are injected in the Steps-Collection. After the asyncrone work is done I can use Validate to check the viewmodel state.
Unfortunately I'm using a ManualResetEvent to wait for the wizard to close. This looks like following:
public class WizardValidator : IValidator, IDisposable
{
private WizardViewModel _dialog;
private readonly ManualResetEvent _dialogClosed = new ManualResetEvent(false);
[..]
public void ListenTo(WizardViewModel dialog)
{
_dialog = dialog;
dialog.RequestClose += (sender, args) => _dialogClosed.Set();
dialog.StepsDefaultView.CurrentChanged += StepsDefaultViewOnCurrentChanged;
_dialogClosed.WaitOne();
}
[..]
}
Now there's a problem:
While the Application is running the UI Thread is not blocked, the Collection can be updated without any problems. But in my testcases the "main" Thread where I initialize the ViewModel (and because of that the Collections) is an AppDomainThread which is blocked by the testcode. Now my ThreadsafeInsert wants to update the collection but cannot use the AppDomain Thread.
But I have to wait for the wizard to finish, how can I solve this kind of deadlock? Or is there a more elegant solution for this one?
edit:
I worked around this problem with a check if there's a user interface, and only then I invoke on the Application-Thread, otherwise I change the collection intentionally on another thread. This does not prevent the exception, but it is not recognized from the test... the items are inserted nevertheless, only the NotifyCollectionChanged-Handler is not called (which is only used in the UI anyway).
if (Application.Current != null)
{
Application.Current.Dispatcher.Invoke(() =>
{
Steps.Insert(pos, step);
stepsView.MoveCurrentTo(step);
});
}
else
{
new Action(() => Steps.Insert(pos, step)).BeginInvoke(ar => stepsView.MoveCurrentToPosition(pos), null);
}
This is an ugly workaround and I am still interested in a clean solution.
Is there a way to use an alternate Dispatcher to create (e.g.) the whole ViewModel and use this to change my collection?
As I see the main problem that main thread is blocked and other operations are trying to be executed in main thread too? What about not to block main thread, like this:
// helper functions
public void DoEvents()
{
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
new DispatcherOperationCallback(ExitFrame), frame);
Dispatcher.PushFrame(frame);
}
public object ExitFrame(object f)
{
((DispatcherFrame)f).Continue = false;
return null;
}
// in your code:
while(!_dialogClosed.WaitOne(200))
DoEvents();
If it will not help then I guess need to try some SynchronisationContext workarounds.
I think the problems boil down to the fact that you create ObservableCollection that is tied to Dispatcher object.
Involving Dispatcher object directly is almost never good idea(as you just witnessed). Instead I would suggest you to see how others have implemented ThreadSafeObservableCollection. This is a little example I put together, it should illustrate the point:
public class ThreadSafeObservableCollection<T> : ObservableCollection<T>
{
private readonly object _lock = new object();
public ThreadSafeObservableCollection()
{
BindingOperations.CollectionRegistering += CollectionRegistering;
}
protected override void InsertItem(int index, T item)
{
lock (_lock)
{
base.InsertItem(index, item);
}
}
private void CollectionRegistering(object sender, CollectionRegisteringEventArgs e)
{
if (e.Collection == this)
BindingOperations.EnableCollectionSynchronization(this, _lock);
}
}

Solve a cross-threading Exception in WinForms

Presently I'm working with WinForms(in C#) and I have to run the application in the background. For this purpose I'm using asynchronous. When I run the application it's showing an exception like
"Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on."
How can I solve this error?
When making method calls to a control, if the caller is on a different thread than the one the control was created on, you need to call using Control.Invoke. Here is a code sample:
// you can define a delegate with the signature you want
public delegate void UpdateControlsDelegate();
public void SomeMethod()
{
//this method is executed by the background worker
InvokeUpdateControls();
}
public void InvokeUpdateControls()
{
if (this.InvokeRequired)
{
this.Invoke(new UpdateControlsDelegate(UpdateControls));
}
else
{
UpdateControls();
}
}
private void UpdateControls()
{
// update your controls here
}
Hope it helps.
Most often, the best way to do this sort of thing with WinForms is to use BackgroundWorker, which will run your work on a background thread, but provide you with a nice clean way to report status back to the UI.
In a lot of everyday .NET programming, explicitly creating threads or calling .Invoke is a sign that you're not using the framework to its full advantage (of course, there are lots of legitimate reasons to do low-level stuff too, it's just that they're less common that people sometimes realise).
You need to check if Invoke is required for the control you're trying to update. Something like this:
Action<Control, string> setterCallback = (toSet, text) => toSet.Text = text;
void SetControlText(Control toSet, string text) {
if (this.InvokeRequired) {
this.Invoke(setterCallback, toSet, text);
}
else {
setterCallback(toSet, text);
}
}
Updated from Invoke to begin Invoke
// you can define a delegate with the signature you want
public delegate void UpdateControlsDelegate();
public void SomeMethod()
{
//this method is executed by the background worker
InvokeUpdateControls();
}
public void InvokeUpdateControls()
{
if (this.InvokeRequired)
{
this.BeginInvoke(new UpdateControlsDelegate(UpdateControls));
}
else
{
UpdateControls();
}
}
private void UpdateControls()
{
// update your controls here
}
A pattern you might find useful is to do a check at the top of functions that interact with the GUI to see whether you are running on the correct thread or not and have the function invoke itself if required. Like this:
public delegate void InvocationDelegate();
public void DoGuiStuff(){
if (someControl.InvokeRequired){
someControl.Invoke(InvocationDelegate(DoGuiStuff));
return;
}
//GUI manipulation here
}
Using this pattern - if you are on the correct thread when the method is called it doesn't invoke itself, but if you are on a different thread it will invoke itself and then return (so the GUI manipulation logic is only ever called once either way).
The UI changes can be done with Control.Invoke() methods, this cross thread exception can be solved using below code snippet.
void UpdateWorker()
{
//Here ddUser is the user control
//Action to be performed should be called within { } as like below code
if (this.ddUser.InvokeRequired)
ddUser.Invoke(new MethodInvoker(() => { ddUser.Size = new Size(100, 100); }));
}
I knew the topic is 10 years old, but I would like to improve the solution for generic through lambda selector instead of defining of each type of setter
private void SetControlSafety<C, V>(C control, Expression<Func<C, V>> selector, V value)
{
if (this.InvokeRequired)
this.Invoke(MyUtils.GetSetter(selector), control, value);
else
DataCrawlerUtils.GetSetter(selector)(control, value);
}
Or static
public static void SetControlSafety<C, V>(C control, Expression<Func<C, V>> selector, V value) where C : Control
{
if (control.InvokeRequired)
control.Invoke(DataCrawlerUtils.GetSetter(selector), control, value);
else
DataCrawlerUtils.GetSetter(selector)(control, value);
}
GetSetter method from here to assign value to a property has been selected through lambda
public static Action<T, TProperty> GetSetter<T, TProperty>(
Expression<Func<T, TProperty>> pExpression
)
{
var parameter1 = Expression.Parameter(typeof(T));
var parameter2 = Expression.Parameter(typeof(TProperty));
// turning an expression body into a PropertyInfo is common enough
// that it's a good idea to extract this to a reusable method
var member = (MemberExpression)pExpression.Body;
var propertyInfo = (PropertyInfo)member.Member;
// use the PropertyInfo to make a property expression
// for the first parameter (the object)
var property = Expression.Property(parameter1, propertyInfo);
// assignment expression that assigns the second parameter (value) to the property
var assignment = Expression.Assign(property, parameter2);
// then just build the lambda, which takes 2 parameters, and has the assignment
// expression for its body
var setter = Expression.Lambda<Action<T, TProperty>>(
assignment,
parameter1,
parameter2
);
return setter.Compile();
}
Then the using is pretty simple
SetControlSafety(txtStatus, x => x.Text, "Loading resources...");
BeginInvoke
It is a good way to prevent a cross-thread exception. I read it in a book "The C# Programmer’s Study Guide (MCSD"
You can use BeginInvoke
BeginInvoke method is used to change values of UI control from other threads. It does it in a thread-safe way. It requires a delegate; it tells which UI control needs to change its value.
private async void button1_Click(object sender, EventArgs e)
{
Task task = Task.Run(() =>
{
this.BeginInvoke(new Action(() =>
{
label1.Text = "Hello";
}));
});
await task;
}
The value of label1.Text shall be changed to “Hello” and no exception will arise because it’s a threadsafe operation.

How to cancel a deeply nested process

I have a class that is a "manager" sort of class. One of it's functions is to signal that the long running process of the class should shut down. It does this by setting a boolean called "IsStopping" in class.
public class Foo
{
bool isStoping
void DoWork() {
while (!isStopping)
{
// do work...
}
}
}
Now, DoWork() was a gigantic function, and I decided to refactor it out and as part of the process broke some of it into other classes. The problem is, Some of these classes also have long running functions that need to check if isStopping is true.
public class Foo
{
bool isStoping
void DoWork() {
while (!isStopping)
{
MoreWork mw = new MoreWork()
mw.DoMoreWork() // possibly long running
// do work...
}
}
}
What are my options here?
I have considered passing isStopping by reference, which I don't really like because it requires there to be an outside object. I would prefer to make the additional classes as stand alone and dependancy free as possible.
I have also considered making isStopping a property, and then then having it call an event that the inner classes could be subscribed to, but this seems overly complex.
Another option was to create a "Process Cancelation Token" class, similar to what .net 4 Tasks use, then that token be passed to those classes.
How have you handled this situation?
EDIT:
Also consider that MoreWork might have a EvenMoreWork object that it instantiates and calls a potentially long running method on... and so on. I guess what i'm looking for is a way to be able to signal an arbitrary number of objects down a call tree to tell them to stop what they're doing and clean up and return.
EDIT2:
Thanks for the responses so far. Seems like there's no real consensus on methods to use, and everyone has a different opinion. Seems like this should be a design pattern...
You can go two ways here:
1) The solution you've already outlined: pass a signaling mechanism to your subordinate objects: a bool (by ref), the parent object itself cloaked in an interface (Foo: IController in the example below), or something else. The child objects check the signal as needed.
// Either in the MoreWork constructor
public MoreWork(IController controller) {
this.controller = controller;
}
// Or in DoMoreWork, depending on your preferences
public void DoMoreWork(IController controller) {
do {
// More work here
} while (!controller.IsStopping);
}
2) Turn it around and use the observer pattern - which will let you decouple your subordinate objects from the parent. If I were doing it by hand (instead of using events), I'd modify my subordinate classes to implement an IStoppable interface, and make my manager class tell them when to stop:
public interface IStoppable {
void Stop();
}
public class MoreWork: IStoppable {
bool isStopping = false;
public void Stop() { isStopping = true; }
public void DoMoreWork() {
do {
// More work here
} while (!isStopping);
}
}
Foo maintains a list of its stoppables and in its own stop method, stops them all:
public void Stop() {
this.isStopping = true;
foreach(IStoppable stoppable in stoppables) {
stoppable.Stop();
}
}
I think firing an event that your subclasses subscribe to makes sense.
You could create a Cancel() method on your manager class, and on each of your other worker classes. Base it on an interface.
The manager class, or classes that instantiate other worker classes, would have to propagate the Cancel() call to the objects they are composed of.
The deepest nested classes would then just set an internal _isStopping bool to false and your long-running tasks would check for that.
Alternatively, you could maybe create a context of some sort that all the classes know about and where they can check for a canceled flag.
Another option was to create a
"Process Cancelation Token" class,
similar to what .net 4 Tasks use, then
that token be passed to those classes.
I am not familiar with this, but if it is basically an object with a bool property flag, and that you pass into each class, then this seems like the cleanest way to me. Then you could make an abstract base class that has a constructor that takes this in and sets it to a private member variable. Then your process loops can just check that for cancellation.
Obviously you will have to keep a reference to this object you have passed into your workers so that it's bool flag can be set on it from your UI.
Your nested types could accept a delegate (or expose an event) to check for a cancel condition. Your manager then supplies a delegate to the nested types that checks its own "shouldStop" boolean. This way, the only dependency is of the ManagerType on the NestedType, which you already had anyway.
class NestedType
{
// note: the argument of Predicate<T> is not used,
// you could create a new delegate type that accepts no arguments
// and returns T
public Predicate<bool> ShouldStop = delegate() { return false; };
public void DoWork()
{
while (!this.ShouldStop(false))
{
// do work here
}
}
}
class ManagerType
{
private bool shouldStop = false;
private bool checkShouldStop(bool ignored)
{
return shouldStop;
}
public void ManageStuff()
{
NestedType nestedType = new NestedType();
nestedType.ShouldStop = checkShouldStop;
nestedType.DoWork();
}
}
You could abstract this behavior into an interface if you really wanted to.
interface IStoppable
{
Predicate<bool> ShouldStop;
}
Also, rather than just check a boolean, you could have the "stop" mechanism be throwing an exception. In the manager's checkShouldStop method, it could simply throw an OperationCanceledException:
class NestedType
{
public MethodInvoker Stop = delegate() { };
public void DoWork()
{
while (true)
{
Stop();
// do work here
}
}
}
class ManagerType
{
private bool shouldStop = false;
private void checkShouldStop()
{
if (this.shouldStop) { throw new OperationCanceledException(); }
}
public void ManageStuff()
{
NestedType nestedType = new NestedType();
nestedType.Stop = checkShouldStop;
nestedType.DoWork();
}
}
I've used this technique before and find it very effective.
Litter your code with statements like this wherever it is most sensible to check the stop flag:
if(isStopping) { throw new OperationCanceledException(); }
Catch OperationCanceledException right at the top level.
There is no real performance penalty for this because (a) it won't happen very often, and (b) when it does happen, it only happens once.
This method also works well in conjunction with a WinForms BackgroundWorker component. The worker will automatically catch a thrown exception in the worker thread and marshal it back to the UI thread. You just have to check the type of the e.Error property, e.g.:
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if(e.Error == null) {
// Finished
} else if(e.Error is OperationCanceledException) {
// Cancelled
} else {
// Genuine error - maybe display some UI?
}
}
You can flatten your call stack by turning each DoWork() call into a command using the Command pattern. At the top level, you maintain a queue of commands to perform (or a stack, depending on how your commands interact with each other). "Calling" a function is translated to enqueuing a new command onto the queue. Then, between processing each command, you can check whether or not to cancel. Like:
void DoWork() {
var commands = new Queue<ICommand>();
commands.Enqueue(new MoreWorkCommand());
while (!isStopping && !commands.IsEmpty)
{
commands.Deque().Perform(commands);
}
}
public class MoreWorkCommand : ICommand {
public void Perform(Queue<ICommand> commands) {
commands.Enqueue(new DoMoreWorkCommand());
}
}
Basically, by turning the low-level callstack into a data structure you control, you have the ability to check stuff between each "call", pause, resume, cancel, etc..

Categories

Resources