我有这种有点复杂的情况。
我给了一个对象o
,一个字符串n
和一个对象数组args
。我将使用给定的参数调用对象n
上的方法o
。
问题是这个输入总是来到同一个线程,并且提供的对象是(有时)在不同线程上创建的控件。所以当我尝试在它们上调用某些方法时,我得到了跨线程调用异常。
如果我可以检查对象是否是一个控件,然后调用它的Invoke
方法并在该调用中执行我的操作,那将不会有问题。不幸的是,我不能这样做,因为我可以传递一个属于某个控件的ControlCollection
对象。如果我将其称为Add
方法,则会收到异常,但ControlCollection
没有Invoke
方法。
我该怎么办?性能不是我所担心的,所以任何解决方案都是好的。也许如果我能捕获异常并获得它想要的线程,那么重复调用?或者也许有一些方法可以让线程成为“属于”的对象?
答案 0 :(得分:3)
你能这样做吗?
Action action = () => o.GetType().GetMethod(n).Invoke(o, args);
if (o is Control)
{
var c = o as Control;
c.Invoke(action);
}
else if (o is ControlCollection)
{
var c = (o as ControlCollection).Owner;
c.Invoke(action);
}
else
{
action();
}
概括这一点的一种方法是这样做:
Action action = () => o.GetType().GetMethod(n).Invoke(o, args);
var controlMaps = new Func<object, Control>[]
{
x => x as Control,
x => o is ControlCollection ? (o as ControlCollection).Owner : null,
};
var c = controlMaps
.Select(m => m(o))
.Where(x => x != null)
.FirstOrDefault();
if (c != null)
{
c.Invoke(action);
}
else
{
action();
}
然后,如果你有一堆不同的对象类型,你可以在controlMaps
数组中创建一个映射。