这是一个清楚的例子,展示了我在上面的评论中所说的内容。它使用锁而不是互斥锁,但你会明白的。这是一个使用多线程作业生产者的简单代码,所有生产者都将信息添加到相同的(锁定的)资源中,并且一个消费者每秒运行一次以与表单控件(在这种情况下为 ListBox)交互并清除作业缓存。
您可以在此处找到更多信息http://www.albahari.com/threading/part2.aspx
public partial class Form1 : Form
{
static readonly Queue<Job> queue = new Queue<Job>();
public Form1()
{
InitializeComponent();
//starts the timer to run the ProcessJobs() method every second
System.Threading.Timer t = new System.Threading.Timer(obj => { ProcessJobs(); }, null, 5000, 1000);
}
/// <summary>
/// Called by informations producers to add jobs to the common queue
/// </summary>
private void AddJob(Job job)
{
lock (queue)
{
queue.Enqueue(job);
}
}
/// <summary>
/// Common queue processing by the consumer
/// </summary>
private void ProcessJobs() {
Job[] jobs;
lock (queue)
{
jobs = queue.ToArray();
queue.Clear();
}
foreach(Job job in jobs){
this.Invoke(new Action(delegate {
listBox1.Items.Add(job.Name);
}));
}
}
/// <summary>
/// Producer
/// </summary>
private void JobsProducer(string name) {
for (int i = 0; i < 10; i++)
{
Random r = new Random();
System.Threading.Thread.Sleep(r.Next(1,10)*50);
this.AddJob(new Job(string.Format("Job({0}) n.{1}", name, i)));
}
}
/// <summary>
/// Starts the jobs producers
/// </summary>
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
string producerName = string.Format("Producer{0}", i);
new System.Threading.Timer(obj => { JobsProducer(producerName); }, null, 0, System.Threading.Timeout.Infinite);
}
}
}
public class Job
{
//whatever -informations you need to exchange between producer and consumer
private string name;
public string Name { get { return name; } }
public Job(string name) {
this.name = name;
}
}
在这里您可以找到一个使用 Dictionary 来保存多个作业结果的示例:
Dictionary<string, string[]> jobs = new Dictionary<string, string[]>();
//adds an array to the dictionary
//NB: (array it's not well suited if you don't know the values or the size in advance...you should use a List<string>)
jobs.Add("jobNumber1", new string[]{"a","b"});
//gets an array from the dictionary
string[] jobNumber1;
if (!jobs.TryGetValue("jobNumber1", out jobNumber1))
throw new ApplicationException("Couldn't find the specified job in the dictionary");