System.Threading计时器tick和后台线程之间的同步

时间:2014-07-30 09:33:19

标签: c# multithreading winforms timer

我需要开发以下场景。我有System.Threating.Timer。在每个计时器滴答声中,从硬件设备检索一些值,这样:

lock (_synch)
{
  //Read some values
}

此外,我在后台线程中调用了许多方法,他们也想在COM上读/写与设备通信,例如:

bool WriteSometghing ()
{
  lock(_synch)
   {
     //Write to device
   }
}

工作正常。所有这些都是应该同步的,没有从线程同时访问设备。但是,我需要异步调用我的WriteSomething方法以防止在后台线程中阻止其他操作。所以WriteSomething应该启动第三个线程,执行所有需要的操作并销毁第三个线程。当然,我还需要确定,没有同时访问硬件。所以它应该与定时器tick上调用的方法同步。此外,我需要同步WriteSomething调用(每次调用都是在UDP数据包接收时触发),因此WriteSomething可以同时调用,但内部的所有操作都应该在WriteSomething调用之间进行同步。

方法WriteSomething必须从后台线程调用,并且还应该从我的后台线程创建第三个线程,代替当前的WriteSomething调用。我可以像我描述的那样简单地创建第三个线程,将WriteSomething放在那里并按原样保留我的锁吗?是否应该在我的3个线程之间进行同步(第一个 - 计时器刻度,第二个 - 后台线程,第三个 - WriteSomething的后台线程)。

你能给我一些提示,应该怎么做?

1 个答案:

答案 0 :(得分:2)

您只需创建Task即可拨打WriteSomething

var task = Task.Factory.CreateNew(WriteSomething);

这将启动一个新线程来执行WriteSomething方法。 lock方法中的WriteSomething将提供必要的同步。如果您想收获返回值,只需访问task.Result

请注意,访问task.Result需要完成任务。所以,如果你写:

var task = Task.Factory.CreateNew(WriteSomething);
var rslt = task.Result;

线程将阻塞,直到任务完成。当然,您可以在开始任务和收获结果之间进行任意处理。

修改

如果您无法使用Task,还有其他方法可以执行此操作。例如:

bool result;
Thread t = new Thread((s) => { result = WriteSomething(); });
// at some point you'll want to harvest the result:
t.Join();
// Now you can access result