当我没有Control可用时如何调用()
我正在编写一个连接处理程序(一个请求用户名和密码的对话框)。 代码是一个显示对话框的处理程序。 这个代码可以从一个线程Invoke()
,所以如果InvokeRequired
我需要Invoke()
。
在理想情况下,我可以初始化然后使用Control
来执行InvokeRequired
处理程序,但有时Control可以为null。 可能吗? 我怎么能实现代码? 以下是否正确?
public class GuiCredentialsHandler { // control used to invoke if needed private static Control mInvokeControl; /// /// Initialize a GetCredentials handler for current process. /// This method should be always called from the main thread, for /// a correctly handling for invokes (when the handler is called /// from a thread). /// /// Application top form. /// Can be null if unknown public static void Initialize(Control parentControl) { if (parentControl != null) { mInvokeControl = parentControl; } else { mInvokeControl = new Control(); // force to create window handle mInvokeControl.CreateControl(); } } public static Credentials GetCredentials() { if (mInvokeControl.InvokeRequired) { return mInvokeControl.Invoke( new GetCredentialsDelegate(DoGetCredentials), null) as Credentials; } else { return DoGetCredentials(); } } private static Credentials DoGetCredentials() { // the code stuff goes here }
}
我的问题是:
- 如果我将null控件传递给
InitializeMethod()
会发生什么 - 如果在UIThread中执行Initialize()方法,代码将在以后工作吗?
- 如果你没有任何控制来测试
InvokeRequired
,推荐的模式是什么?
提前致谢
编辑 :做一些测试,我已经意识到如果我将null传递给Initialize()
,控件没有在UI线程中运行,所以InvokeRequired似乎返回false。 总是。 所以我的问题是,当我无法控制时,如何执行真正的(有效的)调用?
编辑2 :执行mInvokeControl.CreateControl()
解决问题。
一个简单的解决方案是在主线程中创建一个不可见的控件,工作线程可以在其上调用Invoke
。
而是在该类上实现ISynchronizeInvoke 。 这是一个例子:
public class GuiCredentialsHandler : ISynchronizeInvoke { //.... private readonly System.Threading.SynchronizationContext _currentContext = System.Threading.SynchronizationContext.Current; private readonly System.Threading.Thread _mainThread = System.Threading.Thread.CurrentThread; private readonly object _invokeLocker = new object(); //.... #region ISynchronizeInvoke Members public bool InvokeRequired { get { return System.Threading.Thread.CurrentThread.ManagedThreadId != this._mainThread.ManagedThreadId; } } /// /// This method is not supported! /// /// /// /// [Obsolete("This method is not supported!", true)] public IAsyncResult BeginInvoke(Delegate method, object[] args) { throw new NotSupportedException("The method or operation is not implemented."); } /// /// This method is not supported! /// /// /// /// [Obsolete("This method is not supported!", true)] public object EndInvoke(IAsyncResult result) { throw new NotSupportedException("The method or operation is not implemented."); } public object Invoke(Delegate method, object[] args) { if (method == null) { throw new ArgumentNullException("method"); } lock (_invokeLocker) { object objectToGet = null; SendOrPostCallback invoker = new SendOrPostCallback( delegate(object data) { objectToGet = method.DynamicInvoke(args); }); _currentContext.Send(new SendOrPostCallback(invoker), method.Target); return objectToGet; } } public object Invoke(Delegate method) { return Invoke(method, null); } #endregion//ISynchronizeInvoke Members }
注意:由于类实现,它使用System.Threading.SynchronizationContext.Current
因此您可以在WindowsForms
或wpf
使用它,但不能在Console应用程序中使用它,因为System.Threading.SynchronizationContext.Current
为null。