我有一个表格和一些控制权:
public class Tester : Form
{
public Label Demo;
public Label GetDemo()
{
return Demo.Text;
}
}
我也有一些静态类:
public static bool Delay(Func<bool> condition)
{
bool result = false;
AutoResetEvent e = new AutoResetEvent(false);
Timer t = new Timer(delegate {
if (result = condition()) e.Set(); // wait until control property has needed value
}, e, 0, 1000);
e.WaitOne();
t.Dispose();
return result;
}
在某些时候,控件会创建新线程并调用我们的静态方法:
ThreadPool.QueueUserWorkItem(delegate {
if (Delay(() => GetDemo() == "X")) MessageBox.Show("X");
}, null);
当然,这会导致异常,因为GetDemo将传递给Delay,并将作为委托在新线程中调用。
当然,可以通过使用Invoke调用我们的静态方法来解决它:
ThreadPool.QueueUserWorkItem(delegate {
Invoke((MethodInvoker) delegate {
if (Delay(() => GetDemo() == "X")) MessageBox.Show("OK");
}
}, null);
不幸的是,我不允许更改延迟调用,我只能更改其实现。
问题:
1)需要更改的内容INSIDE静态方法延迟,以便condition()在其本机线程中执行GetDemo而没有异常?
2)是否有可能在Delay内做这样的事情?
SynchronizationContext.Dispatcher((Action) delegate {
if (condition()) e.Set();
});
答案 0 :(得分:-1)
此解决方案假定您的代码中还有其他地方可以在UI线程上接收先前的调用,以保存UI SynchronizationContext的副本。情况可能并非如此,在这种情况下,我提议的解决方案不会起作用。
// Assign this using SynchronizationContext.Current from a call made on the UI thread.
private static SynchronizationContext uiSynchronizationContext;
public static bool Delay(Func<bool> condition)
{
bool result = false;
AutoResetEvent e = new AutoResetEvent(false);
Timer t = new Timer(delegate
{
uiSynchronizationContext.Send(s => result = condition(), null);
if (result)
e.Set(); // wait until control property has needed value
}, e, 0, 1000);
e.WaitOne();
t.Dispose();
return result;
}