模仿自定义类/方法的“调用”/“BeginInvoke”样式方法调用

时间:2013-01-22 15:43:51

标签: c# multithreading synchronization

我想创建一个线程安全的方法,我可以从几个worker调用而不会阻塞工作线程。我也希望代码非常简洁,就像InvokeRequired-> BeginInvoke类型代码用于UI控件...当然我在这种情况下我没有使用Control,该方法是在自定义类上。对于每种方法,我也不一定要这样。这样可以在自定义类/方法上轻松实现吗?

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();
    }
}

我想我已经知道如何使用自定义EventArgs执行此操作,但它涉及几乎重复的代码,我正在寻找更通用/更清晰的解决方案。

修改

这是使用C#.Net 4.0

2 个答案:

答案 0 :(得分:3)

鉴于:

  • 您正在使用.NET 4
  • 您提到排队序列化请求...

......听起来你想要一个生产者/消费者队列,通过BlockingCollection<T>。启动一个将从队列中拉出的线程(一个使用者),然后从工作线程中添加到队列中。

如果队列累积到意外/不合需要的级别,您需要考虑要发生的事情。 (你可以阻止,你可以抛出异常,你可以删除请求。)

编辑:有关详细信息,请参阅this MSDN blog post on BlockingCollection<T>

答案 1 :(得分:0)

演示应用于您的任务的生产者/消费者方式的小例子

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();
}

如果你需要更多的counsumer消费所有数据

,你也可以使用ConcurrentQueue