我想创建一个线程安全的方法,我可以从几个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
答案 0 :(得分:3)
鉴于:
......听起来你想要一个生产者/消费者队列,通过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