HodlDwon
HodlDwon

Reputation: 1171

Mimic "Invoke" / "BeginInvoke" Style Method Call on Custom Class/Method

I want to create a thread-safe method I can call from several workers without blocking the worker threads. I also want the code to be decently brief much like the InvokeRequired->BeginInvoke type code is for UI Controls... of course I'm not using a Control in this case, the method is on a custom class. I also don't necessarily want this for every method. So is this something that can be easily implemented on custom classes/methods?

Sudo Code:

class foo
{
    //Fields
    Context MyContext;
    List<T> UnsafeList = new List<T>();

    //Method
    public void MyMethod(int someArg, Item someOtherArg)
    {
        if (!MyContext)
        {
            MyContext.BeginInvoke(...);
            return; //Calling thread returns
        }
        else
        {
            UnsafeList.Add(someOtherArg);
            return; //MyContext Thread returns
        }
    }

    //Constructor
    public foo()
    {
        MyContext = new GetSomeThreadHandle();
    }
}

I think I have an idea of how to do this with custom EventArgs, but it involves nearly repetitive code and I was looking for a more generic/cleaner solution.

Edit

This is using C# .Net 4.0

Upvotes: 0

Views: 578

Answers (2)

gabba
gabba

Reputation: 2880

Little example that demonstrate producer/consumer way applied to the your task

public void produceConsume()
{
    var results = new BlockingCollection<double[]>();

    var producer = Task.Factory.StartNew(() =>
    {
        for (int i = 0; i < 100; i++)
        {
            var data = new double[1024];
            results.Add(data);                    
        }

        results.CompleteAdding();
    });

    var consumer = Task.Factory.StartNew(() =>
    {
        foreach (var item in results.GetConsumingEnumerable())
        {
           // put in chart
        }
    });

    producer.Wait();
}

Also you can use ConcurrentQueue if you need more one counsumer consume all data

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500495

Given that:

  • You're using .NET 4
  • You mentioned queuing and serializing the requests...

... it sounds like you want a producer/consumer queue, via BlockingCollection<T>. Start one thread (a consumer) which will pull from the queue, and then just add to the queue from your worker threads.

You'll need to think about what you want to happen if the queue builds up to an unexpected/undesirable level. (You could block, you could throw an exception, you could drop the requests.)

EDIT: For more information, see this MSDN blog post on BlockingCollection<T>.

Upvotes: 3

Related Questions