views:

120

answers:

3

I have to develop a class which can run it's own hard-coded task in a background thread and communicate with container class sending him progress updates and taking messages from it. I believe I am going to extend BackgroundWorker class but it looks a bit weird to extend and I haven't managed to find a good example wit Google. Can you share a link to a good example of solving such a task? Please don't offer placing a BackgroundWorker visually on a form and reading the standard tutorial, it's not for my case. Maybe I'd better not extend but encapsulate a BackgroundWorker, but I hardly understand how to use it outide WinForms designer either :-(

+1  A: 

You could do it as a Windows Service: http://www.c-sharpcorner.com/uploadfile/mahesh/window_service11262005045007am/window_service.aspx

derek
Thanks for a link, Derek, but I need multiple instances doing multiple different tasks using common data and hardly exposing any service (only that needed to control). I hardly believe that would be a good idea making hundred services, I am going to have to create multiple background work threads in a service anyway. And in a WinForms dashboard app I am again going to communicate to services using background thread (as polling external services in main/GUI thread is unwise).
Ivan
So in my case it looks to be the best idea to implement all the background crunchers as classes inside a class library attached to a WinForms application.
Ivan
+2  A: 

BackgroundWorker will give you no obstacles to get the progress updates implemented, ReportProgress() is there to get that job done. "Sending messages" is another matter though.

You'll need a thread-safe queue in which you can stuff objects that represent a unit of work. Emptied by the BGW in its main loop in the DoWork event handler. .NET 4.0 certainly helps you do that, ConcurrentQueue gets you the queue.

Hans Passant
What I am really looking for is a sample implementation of a custom background-working and communicatible non-visual class in C# 4. Probably extending or encapsulating a BackgroundWorker or something else related. Or at least an example of using BackgroundWorker in a non-visual manner (without using designer).
Ivan
A: 

I'd do it through a callback routine that reports status from the child thread and returns a value from the parent thread. In the following console app sample, I pass a string and return a bool but the arguments could be anything you'd like.

public delegate bool CallbackDelegate(string messageArg);

class Program
{
    static bool running = true;

    static void Main(string[] args)
    {
        for (int i = 0; i < 10; i++)
        {
            Worker worker = new Worker();
            worker.Callback = new CallbackDelegate(WorkerStatus);

            Thread thread = new Thread(new ThreadStart(worker.DoSomething));
            thread.IsBackground = true;
            thread.Start();
        }
        Console.ReadKey(); 
        running = false;
        Console.ReadKey();
    }

    static bool WorkerStatus(string statusArg)
    {
        Console.WriteLine(statusArg);
        return running;
    }
}

public class Worker
{
    public CallbackDelegate Callback { private get; set; }

    public void DoSomething()
    {
        bool keepGoing = true;
        while (keepGoing)
        {
            keepGoing = Callback("Thread ID: " + Thread.CurrentThread.ManagedThreadId.ToString() + " running");
            Thread.Sleep(new Random().Next(100, 2000));
        }
        Callback("Thread ID: " + Thread.CurrentThread.ManagedThreadId.ToString() + " done");
    }
}
ebpower