How to Invoke() when I have no Control available

前端 未结 2 710
逝去的感伤
逝去的感伤 2021-01-24 23:23

I\'m writing a connection handler (a dialog to request username and password). The code is a handler that shows a dialog. This code could be called from a thread, so I need to <

相关标签:
2条回答
  • 2021-01-24 23:56

    Implement ISynchronizeInvoke on that class instead. Here is an example:

    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;
                }
            }
    
            /// <summary>
            /// This method is not supported!
            /// </summary>
            /// <param name="method"></param>
            /// <param name="args"></param>
            /// <returns></returns>
            [Obsolete("This method is not supported!", true)]
            public IAsyncResult BeginInvoke(Delegate method, object[] args)
            {
                throw new NotSupportedException("The method or operation is not implemented.");
            }
    
            /// <summary>
            /// This method is not supported!
            /// </summary>
            /// <param name="method"></param>
            /// <param name="args"></param>
            /// <returns></returns>
            [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
    
    }
    

    Note: Because of the class implementation it uses System.Threading.SynchronizationContext.Current so you can use it in WindowsForms or wpf but not a Console application because the System.Threading.SynchronizationContext.Current is null.

    0 讨论(0)
  • 2021-01-25 00:04

    A simple solution is to create an invisible control in the main thread on which your worker threads can call Invoke.

    0 讨论(0)
提交回复
热议问题