我需要创建一个方法调用,任何线程(例如起见线程B)可以调用,这将在其执行一个特定的给定点处的主要执行的线程(THEAD A)上执行。
示例性的使用情况如下:
static Invoker Invoker = new Invoker();
static void ThreadA()
{
new Thread(ThreadB).Start();
Thread.Sleep(...); // Hypothetic Alpha
Invoker.Invoke(delegate { Console.WriteLine("Action"); }, true);
Console.WriteLine("Done");
Console.ReadLine();
}
static void ThreadB()
{
Thread.Sleep(...); // Hypothetic Beta
Invoker.Execute();
}
调用程序类看起来是这样的:
public class Invoker
{
private Queue<Action> Actions { get; set; }
public Invoker()
{
this.Actions = new Queue<Action>();
}
public void Execute()
{
while (this.Actions.Count > 0)
{
this.Actions.Dequeue()();
}
}
public void Invoke(Action action, bool block = true)
{
ManualResetEvent done = new ManualResetEvent(!block);
this.Actions.Enqueue(delegate
{
action();
if (block) done.Set();
});
if (block)
{
done.WaitOne();
}
}
}
这在大多数情况下细,虽然它不会,如果因为任何原因,执行(并因此Set
)是之前完成WaitOne
,在这种情况下,它只是冻结(它允许线程继续进行,然后块)。 这可能如果阿尔法贝塔>>转载。
我可以使用布尔和诸如此类的东西,但我从来没有在这里得到真正的原子安全。 我尝试了一些修正,但他们不会在Beta版>>阿尔法的情况下工作。
我也想过周围既Invoker.Execute和Invoker.Invoke方法锁定,使我们可以保证的是,执行不和入队等待之间发生的。 然而,问题是,锁也englobes的WaitOne的,因此无法完成(僵局)。
我应该如何去在这种模式得到绝对的安全性原子?
注意:这真的是我这个设计工作,从外部依赖的要求。 因此,改变设计是不是一个真正的选择。
编辑 :我忘了提,我希望有一个阻塞行为(基于bool block
,直至委托上调用调用执行)。