如果知道UI线程为主线程,如何不用Invoke,直接调用主线程执行委托?

解决方案 »

  1.   

    调度是必须的,如果你嫌声明委托麻烦,可以使用SynchronizationContext
      

  2.   

    就是说有2个线程 主线程,子线程
    怎么才子线程里 调用主线程执行ParameterizedThreadStart或者ThreadStart
      

  3.   

    我知道需要调度,但是Invoke的弊端就是必须要知道form或者control
    在我不知道的情况下怎么调用Invoke,
    所以我想知道怎么直接调用主线程来执行指定的委托就是说有2个线程 主线程,子线程
    怎么才子线程里 调用主线程执行ParameterizedThreadStart或者ThreadStart
      

  4.   

    要知道Form或者Control怎么成了弊端了??
      

  5.   

      思想貌似是这样的: 主线程监视者, 子线程通知者, 子线程发出通知,主线程接收到通知由主线程运行. 所以子线程只是起到一个通知的作用,并无实际用途.最简单的实现方法.   主线程 设置一个变量,如:  bool bX = false;通过子线程改变 bX = true;这时候主线程得到 bX值改变,调用相应执行事件。
    不知道是不是这样.
      

  6.   

    在你的主线程中创建一个 空的 Control 控件。
    然后使用这个作为桥梁去 Dispatcher。其实,如果你在非 UI 线程中没有使用 UI 控件,为什么要 Invoke 呢?
      

  7.   

    如果都不知到要调用的form或者control的名字,你怎么调用?
      

  8.   

    我只想知道做法拉....
    算了 我就说下我的需求好了我现在有一个线程队列.可以自由加入线程,当然会加入怎么样的线程委托就不知道了
    OK那么现在这个队列开始运行了....
    可是在运行过程中发现有一个委托抛出异常..不允许跨线程控制控件
    so~~
    说明这个线程中,有一个地方设置了某个控件的值好吧,我现在再次尝试用主线程调用这个委托....(这个地方就写不来了....)over了
      

  9.   

    就是说有2个线程 主线程,子线程
    怎么才子线程里 调用主线程执行ParameterizedThreadStart或者ThreadStart我觉得这个必须主线程执行
    可以设置个Mutex或者其他类似的东西。
    主线程等待,子线程给信号
      

  10.   

    我觉得这只能从业务上查。
    你如果不知道那个窗体的哪个控件导致的异常,就很难了。
    C#能不能向VC++一样把窗口句柄或指针作为参数传到线程里,在线程中还能还原出这个窗口对象?
      

  11.   

    没觉得传送Form也是一种解耦么少年,自己再弄个UI接口吧少年。
      

  12.   


    这个队列只是管理线程的 线程里不一定会有form或者别的控件啊
    怎么能让调用的人一定要传送呢?
    再说调用的人可能也是接受其他地方传过来的委托,,所以传form是不现实的
      

  13.   


    其实我的意思就是说 C#中有没有这样的方法 知道某个线程的id 能不能传送一个委托让这个线程运行
      

  14.   


    调用这两个东西本来就不应该在什么窗口线程中去调用。首先这个要明确,否则你就会去跑到窗体线程上去“排队”去了,而不是真正去使用多线程去处理数据。只有当处理数据完成之后,需要在窗体上的控件显示结果时,才需要调用这个控件的Invoke。这时候你自己应该知道该是哪一个窗体(控件)。例如最次地,它可能是 ApplciationContext.MainForm。
      

  15.   


    你这可能还是函数式思维习惯,以为什么都是“调用函数、得到返回值、在用返回值调用下一个函数....”。多线程编程,就是在调用一个方法时将它需要的参数(你这里就是将来要显示的控件)作为参数传递给它。如果不预先传递给它,那么你就只能得到阻塞式的所谓多线程程序(假的多线程程序),也就是产生线程的过程要等到所谓的线程执行之后再“取得”结果再来决定显示到哪里,这就不是多线程编程的正确思维。多线程编程就是要预先传送form,然后一旦产生线程之后就不管之后的逻辑了(交给线程程序去处理之后的逻辑了)。否则就是函数式思维方式了。
      

  16.   

    对于工具类的多线程程序,既然不传form,就不要显示什么东西。“调用的人可能也是接受其他地方传过来的委托”,那么这个所谓的委托应该去显示结果,这个所谓“调用的人”应该把结果作为参数去调用这个“其他地方传过来的委托”。
      

  17.   

    Everything is about Message Loop
    Thread中有一个很大的while不断执行推送到MessageQueue中的Code Block,现在Invoke就是将block加入到MQ中
    换个角度考虑问题
      

  18.   

    不用invoke ,在win32下的做法是发送消息
    sendmessage or postmessage
      

  19.   

    不合规范,当然不Debug是不会报错的。
      

  20.   

    1 使用Invoke 等价API SendMessage
    2 使用BeginInvoke 等价API PostMessage
    3 设置CheckForIllegalCrossThreadCalls = false
      

  21.   


    少年,多线程的每个线程应该是独立的,可重用的,如果依赖Form,那只能说是伪多线程,因为必定要用到主线程来更改Form信息。再说一下红字,是的线程里不一定有form或者别的控件,可是到时候万一有了,你要怎么办,重新写还是大改?
      

  22.   

    你这里也说的很明白了,你接受的是一个委托,这个委托内部去设置某个控件。那么这里一旦出现问题,责任就在写委托的人身上了,既然这个委托是跑在多线程中的,那么委托内实现方法就应该注意控件的操作,不能直接操作,而应该Invoe回调执行。
    你又说:“我知道需要调度,但是Invoke的弊端就是必须要知道form或者control
    在我不知道的情况下怎么调用Invoke”。这个委托内部去设置的那个控件本身,对委托编写者来说不是知道的吗?他写委托的时候为什么不能Invoke回调去设置控件的值呢?
      

  23.   


    在窗体构造方法中加入下一行代码:System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;当非创建这个控件的线程访问、修改这个控件可能会导致不可预知的后果。所以不推荐跨线程访问控件。
      

  24.   


    也就是说系统的Invoke 就是用SendMessage来实现的喽?
      

  25.   

    只是 Control 控件 Invoke 和 BeginInvoke 呼叫的函数。        private Object MarshaledInvoke(Control caller, Delegate method, Object[] args, bool synchronous) {             // Marshaling an invoke occurs in three steps:
                //
                // 1.  Create a ThreadMethodEntry that contains the packet of information 
                //     about this invoke.  This TME is placed on a linked list of entries because
                //     we have a gap between the time we PostMessage and the time it actually 
                //     gets processed, and this gap may allow other invokes to come in.  Access 
                //     to this linked list is always synchronized.
                // 
                // 2.  Post ourselves a message.  Our caller has already determined the
                //     best control to call us on, and we should almost always have a handle.
                //
                // 3.  If we're synchronous, wait for the message to get processed.  We don't do 
                //     a SendMessage here so we're compatible with OLE, which will abort many
                //     types of calls if we're within a SendMessage. 
                //             if (!IsHandleCreated) { 
                    throw new InvalidOperationException(SR.GetString(SR.ErrorNoMarshalingThread));
                }            // We have to demand unmanaged code permission here for the control hosted in 
                // the browser case. Without this
     
      
                ActiveXImpl activeXImpl = (ActiveXImpl)Properties.GetObject(PropActiveXImpl);
                if (activeXImpl != null) { 
                    IntSecurity.UnmanagedCode.Demand();
                } 
     
                // We don't want to wait if we're on the same thread, or else we'll deadlock.
                // It is important that syncSameThread always be false for asynchronous calls. 
                //
                bool syncSameThread = false;
                int pid; // ignored
                if (SafeNativeMethods.GetWindowThreadProcessId(new HandleRef(this, Handle), out pid) == SafeNativeMethods.GetCurrentThreadId()) { 
                    if (synchronous)
                        syncSameThread = true; 
                }             // Store the compressed stack information from the thread that is calling the Invoke() 
                // so we can assign the same security context to the thread that will actually execute
                // the delegate being passed.
                //
                ExecutionContext executionContext = null; 
                if (!syncSameThread) {
                    executionContext = ExecutionContext.Capture(); 
                } 
                ThreadMethodEntry tme = new ThreadMethodEntry(caller, method, args, synchronous, executionContext);
     
                lock (this) {
                    if (threadCallbackList == null) {
                        threadCallbackList = new Queue();
                    } 
                }
     
                lock (threadCallbackList) { 
                    if (threadCallbackMessage == 0) {
                        threadCallbackMessage = SafeNativeMethods.RegisterWindowMessage(Application.WindowMessagesVersion + "_ThreadCallbackMessage"); 
                    }
                    threadCallbackList.Enqueue(tme);
                }
     
                if (syncSameThread) {
                    InvokeMarshaledCallbacks(); 
                }  else { 
                    //
     
                    UnsafeNativeMethods.PostMessage(new HandleRef(this, Handle), threadCallbackMessage, IntPtr.Zero, IntPtr.Zero);
                }            if (synchronous) { 
                    if (!tme.IsCompleted) {
                        WaitForWaitHandle(tme.AsyncWaitHandle); 
                    } 
                    if (tme.exception != null) {
                        throw tme.exception; 
                    }
                    return tme.retVal;
                }
                else { 
                    return(IAsyncResult)tme;
                } 
            } 
      

  26.   

    这仅仅是对微软的内置方法Control.Invoke(Delegate method, Object[] args)进行的反编译而已,里面用到了很多微软私有类和方法,根本不能使用,居然成了最佳答案?我非常怀疑楼主的人品是不是有问题。