Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Executing delegate in a different thread

Executing delegate in a different thread

Scheduled Pinned Locked Moved C#
helpquestioncsharpsysadmin
6 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Artur Lowen
    wrote on last edited by
    #1

    I have a problem while trying to execute a delegate in a different thread. I have my application and autocad that has loaded my .net-dll. I created a named-pipe-server (in an own thread in the dll for autocad) and send messages to it from my application. The thread with the server watis for the messages and executes a delegate on receiption. The method in my class (in the dll) is called and I can show it with a messagebox. Till here everything is fine. But now I want to open a new file for autocad and I try to use the regarding method-call (AcadApp.Application.DocumentManager.Open(file)). But here is the problem. I get an exception about internal error or wrong context. I'm still in the thread-context of my listening server and I think that is the problem. But how can I execute a function in the autocad-thread? My initialization-function that creates the listening-thread is executed in the autocad-thread-context so I can get Thread-object or whatever is needed.

    L 1 Reply Last reply
    0
    • A Artur Lowen

      I have a problem while trying to execute a delegate in a different thread. I have my application and autocad that has loaded my .net-dll. I created a named-pipe-server (in an own thread in the dll for autocad) and send messages to it from my application. The thread with the server watis for the messages and executes a delegate on receiption. The method in my class (in the dll) is called and I can show it with a messagebox. Till here everything is fine. But now I want to open a new file for autocad and I try to use the regarding method-call (AcadApp.Application.DocumentManager.Open(file)). But here is the problem. I get an exception about internal error or wrong context. I'm still in the thread-context of my listening server and I think that is the problem. But how can I execute a function in the autocad-thread? My initialization-function that creates the listening-thread is executed in the autocad-thread-context so I can get Thread-object or whatever is needed.

      L Offline
      L Offline
      Laddie
      wrote on last edited by
      #2

      You can try using MethodInvoker inside your thread to invloke the function in another thread.

      Thanks Laddie Kindly rate if the answer was helpful

      A 1 Reply Last reply
      0
      • L Laddie

        You can try using MethodInvoker inside your thread to invloke the function in another thread.

        Thanks Laddie Kindly rate if the answer was helpful

        A Offline
        A Offline
        Artur Lowen
        wrote on last edited by
        #3

        How does it work? Can you give me a sample? As you see I tried something but it doesn't work. my code:

        class IPCMsgHandler
        {
        private Thread listenThread = new Thread(ListeningThreadFunc);

        ...

        public void Start()
        {
        	listenThread.Start(this);
        }
        
        private static void ListeningThreadFunc(object data)
        {
        	IPCMsgHandler helper = data as IPCMsgHandler;
        
        	...
        
        	//helper.OnMessage(); doesn't work...staying in current thread context
        
        	MethodInvoker mi = new MethodInvoker(helper.OnMessage);
        	mi.Invoke();
        
        	...
        }
        

        }

        public class AutoCADApplication : IExtensionApplication
        {
        IPCMsgHandler helper = null;

        public void Initialize()
        {
        	// I have the right execution-context here
        	this.helper = new IPCMsgHandler("AutoCAD-IPCServer", new IPCMsgHandler.MessageHandler(this.OnIPCMessage));
        	this.helper.Start();
        }
        private void OnIPCMessage()
        {
        	// I have the WRONG execution-context here
        	return;
        }
        
        T 1 Reply Last reply
        0
        • A Artur Lowen

          How does it work? Can you give me a sample? As you see I tried something but it doesn't work. my code:

          class IPCMsgHandler
          {
          private Thread listenThread = new Thread(ListeningThreadFunc);

          ...

          public void Start()
          {
          	listenThread.Start(this);
          }
          
          private static void ListeningThreadFunc(object data)
          {
          	IPCMsgHandler helper = data as IPCMsgHandler;
          
          	...
          
          	//helper.OnMessage(); doesn't work...staying in current thread context
          
          	MethodInvoker mi = new MethodInvoker(helper.OnMessage);
          	mi.Invoke();
          
          	...
          }
          

          }

          public class AutoCADApplication : IExtensionApplication
          {
          IPCMsgHandler helper = null;

          public void Initialize()
          {
          	// I have the right execution-context here
          	this.helper = new IPCMsgHandler("AutoCAD-IPCServer", new IPCMsgHandler.MessageHandler(this.OnIPCMessage));
          	this.helper.Start();
          }
          private void OnIPCMessage()
          {
          	// I have the WRONG execution-context here
          	return;
          }
          
          T Offline
          T Offline
          The Nightcoder
          wrote on last edited by
          #4

          Hi, You need a reference to a control that has a window handle associated with it (something that inherits from System.Windows.Forms.Control) and lives on the Autocad main thread. Possibly you can get that through the Autocad API (with which I'm not at all familiar). If you have that reference in a variable called control you invoke your delegate with control.Invoke(mi) instead of mi.Invoke(). This routes the invocation through the event queue on the UI thread, which should solve your problem. Assuming you can get your hands on a suitable Control object of course...

          -- Peter

          B 1 Reply Last reply
          0
          • T The Nightcoder

            Hi, You need a reference to a control that has a window handle associated with it (something that inherits from System.Windows.Forms.Control) and lives on the Autocad main thread. Possibly you can get that through the Autocad API (with which I'm not at all familiar). If you have that reference in a variable called control you invoke your delegate with control.Invoke(mi) instead of mi.Invoke(). This routes the invocation through the event queue on the UI thread, which should solve your problem. Assuming you can get your hands on a suitable Control object of course...

            -- Peter

            B Offline
            B Offline
            Bekjong
            wrote on last edited by
            #5

            That would work for a windows forms based API, and although I don't know the Autocad API either I wouldn't expect it to be Forms based. A better bet might be to implement a producer/consumer type of architecture[^].

            Standards are great! Everybody should have one!

            T 1 Reply Last reply
            0
            • B Bekjong

              That would work for a windows forms based API, and although I don't know the Autocad API either I wouldn't expect it to be Forms based. A better bet might be to implement a producer/consumer type of architecture[^].

              Standards are great! Everybody should have one!

              T Offline
              T Offline
              The Nightcoder
              wrote on last edited by
              #6

              True... but the API might contain something similar. I'd look around for a method called Invoke() on objects exposed by it. That mechanism isn't specific to Windows.Forms.Control, but to the System.ComponentModel.ISynchronizeInvoke interface, which is implemented by controls. Chances are that there is something similar available (there should be, if cross-thread calls are an issue). However... I don't seem to remember the "wrong execution context" error message from inadvertently doing cross-thread method invocations in Windows.Forms. This could be something completely different. If it has anything to do with a System.Threading.ExecutionContext, there is something seriously broken in AutoCAD or its API. In the code presented, the OnIPCMessage() method shouldn't care less about from which thread it is invoked, and even if it did, the ExecutionContext should be just fine (it gets copied when the managed thread is started). Or could it be that the code causing the problem isn't included in the post? Nite!

              -- Peter

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups