Returning status from a worker class - c#

I have a service class and a worker class. The worker class does all the processing.
class WorkerClass
{
public void ProcessWork(<params to the method>)
{
// Get the tasks from the DB.
// Call a 3rd party web service to process each of the tasks.
}
}
In my service class, I instantiate the worker class and call the method. The question is, how do I get the number of tasks processed in the service class?
I have thought of 3 options:
Expose an event from the worker class. Hook up an event handler in the service class.
Modify the signature of ProcessWork method so that it accepts a delegate:
public void ProcessWork(object obj1, Action<int, int> actionProgressTracker)
Expose a property from the worker class and get the property in the service class. Refresh the property every 30 seconds.
What would be a clean way of getting the status?

The first two options are really functionally identical. Both can work just fine for what you need to do. The second has an implication that the delegate is required, whereas the first implies that it is not. An event might also imply that it is used beyond the scope of just this one method.
As for the third option, it doesn't give the caller the opportunity to execute code when the number updates, it just gives them the opportunity to access the information.
So if the caller of this type is going to need to do something with this information *every time the value changes) then you should be using something comparable to one of the first two options so that the worker can "push" information to the caller.
If the caller wants to "pull" the information from the worker whenever it wants the information, then go with the third option.
Note that there is also a Progress class that you can use, with a corresponding IProgress interface, that's comparable to your first two options, but is specifically tailored for a worker updating a UI with progress.
Both push and pull methods can actually be sensible for updating a UI with progress of a backround task. If progress occurs infrequently it may make sense to update the UI every time progress changes, so the UI will want to be "notified" of when those updates happen. If the updates are very frequent, then the UI may want to instead have a timer and pull the current status every so often, to avoid taxing the UI with more updates than are needed or than it can handle.
Of course, if you're pushing information and not just something like a percent complete, then it may be important to not lose any of that information, in which case your 3rd approach isn't an option, as multiple updates may happen in between fetches.
And of course if you're writing a sufficiently generalized worker, you may want to expose both a push and pull mechanism, to let the caller choose the appropriate one.

Related

Cancelling a background worker without worker.CancellationPending check?

I have a Validator class which has a Validate function, This validate function loops over bunch of file and validates them. User can cancel the validate process.
For cancelling the back ground worker I need ta reference of the background worker instance in Validtor class (for cancelling the validation process) and call CancellationPending on it.
But the problem is Validator class can't have reference to background worker because there are times when we call the "Validate" function synchronously and Validator class does not have to know this.
So far I have tried replacing backgroundworker.CancellationPending check with some flag e.g. IsCanceled which do not seems to work.
You have two options:
Make two overloads of the Validate method. One that is synchronous and one that is asynchronous and cancellable.
Change your Validate method so that the calling code is responsible for looping over the files (consider an iterator method, using yield)
I'd go with option 1 as it is a smaller change.

C# pub/sub service - how to fire events on background threads?

I've developed some code that receives a series of values from a hardware device, every 50ms in the form of name/value pairs. I want to develop a pub/sub service whereby subscribers can be notified when the value of a particular item changes. The Subscribe method might look something like this:-
public void Subscribe(string itemName, Action<string, long> callback)
The code that reads the hardware values will check if a value has changed since last time. If so, it will iterate through any subscribers for that item, calling their delegates. As it stands, the delegates will be called on the same thread which isn't ideal - I need to keep the polling as fast as possible. What's the best approach for calling the callback delegates on separate threads? Should the subscribers pass in (say) a task/thread, or should the publisher be responsible for spinning these up?
Note that I need to pass a couple of parameters to the delegate (the item name and its value), so this might affect the approach taken. I know you can pass a single "state" object to tasks but it feels a bit unintuitive requiring the subscribers to implement an Action callback delegate (which must then be cast to some other type containing the name and value).
Also, I'm assuming that creating a new task/thread each time a delegate is called will hurt performance, so some kind of "pool" might be required?
I would maintain the same structure that you now have and put the responsibility of prompt action onto the callbacks, ie. the callbacks should not block or perform complex, lengthy actions directly.
If a particular callback needs to perform any lengthy action, it should queue off the Action data to a thread of its own and then return 'immediately', eg. it might BeginInvoke/PostMessage the data to a GUI thread, queue it to a thread that inserts into DB table or queue it to a logger, (or indeed, any combo chained together). These lengthy/blocking actions can then proceed in parallel while the device interface continues to poll.
This way, you keep the working structure you have and do not have to inflict any inter-thread comms onto callbacks that do not need it. The device interface remains encapsulated, just firing callbacks.
EDIT:
'creating a new task/thread each time a delegate is called will hurt performance' - yes, and also it would be difficult to maintain state. Often, such threads are written as while(true) loops with some signaling call at the top, eg. a blocking queue pop(), and so only need creating once, at startup, and never need terminating.

Ordering of Asynchronous method calls

I am working on a class library that logs audit details of a web application in several types of datasources(file, xml, database) based on policies defined in the web configuration file.
My Audit log method has a signature similar to this:
public static void LogInfo(User user, Module module, List lst);
Web application uses this method to log important pieces of details like warnings, error and even exception details.
Since in a single workflow, there are more than 700+ calls to these methods , I thought of making them asynchronous. I used simple method from ThreadPool class called QueueUserWorkItem
ThreadPool.QueueUserWorkItem(o => LogInfo(User user, Module module, List<Object> lst) );
but this does not ensure the order in which work item was queued to it. Even though all my information was logged but entire ordering was messed up. In my text file my logs were not in the order in which they were called.
Is there a way I can control the ordering of the threads being called using QueueUserWorkItem?
I don't think you can specify ordering when using QueueUserWorkItem.
To run the logging in parallel (on some background thread), you could use ConcurrentQueue<T>. This is a thread-safe collection that can be accessed from multiple threads. You could create one work item (or a thread) that reads elements from the collection and writes them to a file. Your main application would add items to the collection. The fact that you're adding items to the collection from a single thread should guarantee that they will be read in the right order.
To keep things simple, you can store Action values in the queue:
ConcurrentQueue<Action> logOperations = new ConcurrentQueue<Action>();
// To add logging operation from main thread:
logOperations.Add(() => LogInfo(user, module, lst));
The background task can just take Actions from the queue and run them:
// Start this when you create the `logOperations` collection
ThreadPool.QueueUserWorkItem(o => {
Action op;
// Repeatedly take log operations & run them
while (logOperations.TryDequeue(out op)) op();
});
If you need to stop the background processor (that writes data to the log), you can create a CancellationTokenSource and also end the while loop when the token is being cancelled (by the main thread). This cha be checked using IsCancellationRequested property (see MSDN)
One way of solving this would be to put your data in a queue, and then having a single task picking from that queue and writing them in order. If you are using .net 4.0 You could use ConcurrentQueue, which is thread safe, otherwise a simple Queue with proper locks would work as well.
The thread consuming the queue could then periodically check for any element inside the queue, and for each one of them it could log. This way the lengthy operation (logging) could be in its own thread, whereas in the main thread you do simply adds.

Preferred way of passing data across threads

I have a main thread which should process data coming from several worker threads.
But this data is not a specific class.
There are around 6-7 classes, and I need to pass one of this class to the main thread from worker threads.
Previously I had only one class which was passed across threads. I was using;
BlockingCollection<MyClass> mainQueu = new BlockingCollection<MyClass>(new ConcurrentQueue<MyClass>());
So I was pushing MyClass instances from several threads to mainQueu and main thread was trying to take from the mainQueu.
But what if I have more than one classes. Which way is better?
Having a queue for each type of class:
Of course there should be another queue of type maybe enum, specifying which class is pushed to the queue. And main thread always tries to take from this queue. As soon as any item comes, it will takes from related queue.
Casting:
Having only one main queue, and in mainQueue class, I can have object member.
And enum which specifies type of object member.
And I can convert class to object when pushing to queue, and than in main thread I can cast it back to original class.
Hope it is clear.
Many thanks,regards
A useful trick here is to just have the worker as a queue of delegates; for example, Action. Then the caller can enqueue the appropriate method and (via captured varialbes) any necessary state.
Say, for example, you have a void Enqueue(Action) method; the caller could do:
queue.Enqueue(targetObject.Method);
(where targetObject.Method is a void Method() {...}), or can do something like:
queue.Enqueue(() => SomeMethod(foo, bar, 123));
(where foo and bar are local to the code that wants the work done)
so we've passed lots of state at once, and not once had to think about types - just operations.

Force event handler to run on object's thread, C# .NET

I have a class that handles events created by multiple member objects. Events from these objects spawn worker threads for the event, so that the various event handlers in my class are running on different threads (one is a serial handler, one is a timer event, etc.) I'm looking for a simple way to make my code thread-safe, preferably by forcing the event handlers to run on my object's thread.
If this were a Forms UI object, I could take advantage of its implementation of the ISynchronizeInvoke interface, and make calls to InvokeRequired, Invoke, etc. In WPF I could use a Dispatcher object. But my class needs to run *independently of any UI code.
Here's a simplified example of what I have:
public class MyClass
{
private SomeObject object1;
private AnotherObject object2;
public MyClass()
{
object1 = new SomeObject();
object2 = new AnotherObject();
object1.AThreadedEvent += ThreadedEventHandler1;
object2.AnotherThreadedEvent += ThreadedEventHandler2;
}
// This runs in its own thread!
private void ThreadedEventHandler1()
{
// DO STUFF HERE
}
// This runs in its own thread!
private void ThreadedEventHandler2()
{
// DO STUFF HERE
}
}
Because both event handlers access the same objects in the parent class (including each-other!), it would be awesome if there were a simple way to force the event handlers to run in the creating object's thread.
I've toyed with the idea of having my class implement the ISynchronizeInvoke interface, but it appears that doing so can get pretty complicated. Before I jump down that rabbit hole, I thought I'd ping the experts to see if there is a more simple solution.
Thoughts?
EDIT:
Part of the reason I want to run the event handlers in the parent object's thread is because the parent object has it's *own events that are triggered based on the events sent by its member objects. I'd like any threading functionality to be hidden by this class, so that code that uses the class doesn't have to worry about thread-related issues (ie. locks and so on). Simply locking shared data won't do the job, because I *still need to trigger events from within the threaded event handlers.
The ideea of invoking on another thread is hand to hand with having a while loop that from time to time it checks whether there is an "outside" message to be processed. For UI, there is the windows loop that does that. For an external thread, you must write manually a loop. Imagine a situation without a loop and that you have a relative long running thread right ? and sudently you want to interrupt this thread to invoke your message and resume what it was doing ON THE SAME shared stack memory. This interruption would destroy your stack. This is simply NOT possible. The other possibility is to use a synchronization mechanism such as ManualResetEvent and just wait for a signal (a signal that comes outside your thread). So, to resume, in order to process a message from another thread, you basically have only two options:
1) You have a while loop, eventually using a little sleep (to give some time / ticks to other threads to do their job)
while (true) {
Thread.Sleep (5);
if (someMessageArrived) { ... }
}
2) You just wait for a message implementing somehow the producer / consummer architecture:
On listening thread:
aManualResetEvent.WaitOne ();
On the "producer" thread:
aManualResetEvent.Set ();
There are advanced classes in .NET framework that might help such as BlockingCollection.
Hope this helps
Assumming, that your class runs in its own thread that the only logic is to execute the incomming calls from other threads, this would be the solution:
(comments inside)
public class MyClass
{
private SomeObject object1;
private AnotherObject object2;
public MyClass()
{
object1 = new SomeObject();
object2 = new AnotherObject();
object1.AThreadedEvent += ThreadedEventHandler1;
object2.AnotherThreadedEvent += ThreadedEventHandler2;
}
// This runs in its own thread!
// Only add the real function call to the queue
public void ThreadedEventHandler1()
{
tasks.Add(ThreadedEventHandler1_really);
}
private void ThreadedEventHandler1_really()
{
// DO STUFF HERE
}
// This runs in its own thread!
// Only add the real function call to the queue
public void ThreadedEventHandler2()
{
tasks.Add(ThreadedEventHandler2_really);
}
// here is the actual logic of your function
private void ThreadedEventHandler2_really()
{
// DO STUFF HERE
}
// the queue of the tasks
BlockingCollection<Action> tasks = new BlockingCollection<Action>();
// this method never returns, it is blocked forever
// and the only purpose of i is to do the functions calls when they added to the queue
// it is done in the thread of this instance
public void StartConsume()
{
foreach (Action action in tasks.GetConsumingEnumerable())
{
// add logic before call
action();
// add logic after call
}
}
}
The solution based on that the caller threads tat calls the functions: ThreadedEventHandler1 and ThreadedEventHandler2, actually add the real call to the queue and emediately continue with their run.
From the other hand, StartConsume function iterates the queue and makes the calls of the added method calls. If you want to add another logic before and after call, you can add it in this function.
Hope it helped to achieve your goal.
Without completely understanding the rational behind your design. I can say that the problem you are trying to solve was solved many times before.
I will assume your main object is like a service which expects calls (in this case events) from itself and other services (the sub objects). If you would think about it in terms of services (which you arguably should) WCF solves that problem for you doing all the heavy lifting #Rami suggested.
You define the main service with the following behavior:
Instance Context Mode - Single
Concurrency Mode - Single
More about these here.
And every event handler would call that main service notifying it about the event.
I am pretty sure you would not go that far and implement every class as a service, but thought it is worth offering anyway as an option.
OK, based on all of your feedback (thanks!) I have a solution to my problem. The short answer: what I wanted to do isn't possible.
Here are more details for those who asked. I'm writing a DLL that manages a device attached to a serial port. This includes basic serial port COM (packet TX and RX, including parsing), and higher-level protocol behavior (TX, Ack, retry on timeout, etc.) The serial port event handlers provided by .NET are obviously asynchronous, as are the System.Timers.Timer objects that I use to handle timeouts, etc.
I am building the code around an MVVM architecture, so that my UI doesn't have any logic in it whatsoever. Hence my need to avoid exploiting Dispatcher or Invoke functionality provided by the UI.
What I was looking for was a way to handle asynchronous events within my DLL in the same simple manner provided by WinForms and WPF. But as has been pointed out, and as I learned when digging deeper, what you are *really doing when you call BeginInvoke or a Dispatcher is pushing something onto a queue, to be consumed later by a different thread polling the queue. Outside the context of a UI, no such polling architecture exists.
SO. My options are to lock the shared objects in my class to make it thread safe, or to implement my own polling architecture within another thread (to avoid blocking the program that uses the DLL) that emulates what the UI code already does.
In either case, the UI code will still need to use its Invoke or equivalent tools when handling events from the DLL class. I suppose that's OK.

Categories

Resources