1
在阅读了如何使用Invoke从其他线程更新GUI元素之后,我对它做了一些工作,并以下面的方法来处理它。我相当肯定我对解决方案过于复杂,但我确实相信它是按预期工作的。使用Invoke处理来自其他线程的调用。这是一个很好的模式?
我用这种方法看到的优点是,它允许一旦GUI线程准备就绪,并且命令的顺序保持不变,多个命令可以短时间连续存储以供使用。缺点是,对我来说,存储这些临时参数看起来效率低下(我可以创建一个通用类来存储所有隐藏它们到单个对象)
我选择重复使用相同的互斥对所有调用,但不同的可能只要他们搭配起来就可以使用。
那么还有什么其他模式可以用来获得相同的结果? (希望在一个不太令人费解的做法)
//The main form class.
public class GUIHandler
{
Mutex InvokeOnce = new Mutex(); //Mutex that ensures that temp storage only gets written to or read from
//tempData for Invoke Methodes
List<SomeObject> invokeParameter = new List<SomeObject>();
List<SomeOtherObject> anotherInvokeParameter = new List<SomeOtherObject>();
public GUIHandler()
{
//Some code to initialize the GUI
}
//Generic Reused InvokeDelegate
public delegate void InvokeDelegate();
//External Call with parameters different calls different names
private void SomeInvokeRequiredAction(SomeObject someParameter)
{
//call mutex for handle the storage and store the parameter
InvokeOnce.WaitOne();
invokeParameter.Add(someParameter);
InvokeOnce.ReleaseMutex();
this.BeginInvoke(new InvokeDelegate(SomeInvokeRequiredActionInvoke));
}
//Invoked Code with related name to its primary external call
private void SomeInvokeRequiredActionInvoke()
{
InvokeOnce.WaitOne();
//some random action on a GUI element that required the Invoke in first place
guiElement.Text = invokeParameter[0]
invokeParameter.RemoveAt(0);
InvokeOnce.ReleaseMutex();
}
}
使用的invoke()代替BeginInvoke()不太复杂。不需要锁定,因为只有一个线程可以同时访问列表。然而,它当然不是更有效率。一次调用单个数据项通常是一个非常糟糕的主意,因此调用UI线程的几率很高。你只有人的眼睛才能娱乐,他们看不到每秒超过25次更新的内容。 –
你可能想看看这个问题,它的答案是:[自动化InvokeRequired代码模式](http://stackoverflow.com/questions/2367718/automating-the-invokerequired-code-pattern) –
典型的我使用lambdas捕获用于存储用于调用的变量。它是类型安全的,并且需要存储变量的类是在编译时为您创建的。 – Aron