Author Topic: Background Workers  (Read 32 times)

0 Members and 1 Guest are viewing this topic.

jtoverka

  • Newt
  • Posts: 98
Background Workers
« on: Today at 12:45:51 PM »
So to start,
I am aware that AutoCAD applications cannot have multiple threads running at the same time.
This is a hack that I am implementing and I only need to solve one tiny piece of the puzzle.

Before I go any further, I want to say that RealDWG is not in the cards for me at the moment.

So I am using accoreconsole.exe for my application. This is that console only command line interface. The idea is that I have the main application independent of AutoCAD running. When I need to perform an AutoCAD operation, I simply open the core console in the background (no console window displayed) and run the worker as an instance within the console. The worker needs to communicate back to the main Application. This is where I need help. The worker communicating to the main application. The main application needs to run code that only AutoCAD can execute.

So here is where I am at. I have a .NET Framework 4.7 project called LoadConsole with two files:
Program.cs
Code: [Select]
namespace LoadConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            LoadConsole.Console console = new LoadConsole.Console();
        }
    }
}

Console.cs
Code: [Select]
using System;
using System.Diagnostics;
using System.IO;

namespace LoadConsole
{
    /// <summary>
    /// Launches the accoreconsole and loads CAD UI.dll and opens main window
    /// </summary>
    public class Console
    {
        #region Fields

        private readonly Process coreprocess = new Process();

        #endregion

        #region Properties

        /// <summary>
        /// connected to loaded program in accoreconsole.
        /// </summary>
        public bool Connected { get; protected set; }

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of this class
        /// </summary>
        public Console()
        {
            try
            {
                string installpath = null;

                // Search the directory for the AutoCAD Console Application
                foreach (string file in Directory.GetFiles(@"C:\Program Files\Autodesk\", "accoreconsole.exe", SearchOption.AllDirectories))
                {
                    if (Path.GetFileName(file).Equals("accoreconsole.exe", StringComparison.OrdinalIgnoreCase))
                    {
                        installpath = file;
                        break;
                    }
                }

                // Set Process arguments
                coreprocess.StartInfo.Arguments = "/isolate";
                coreprocess.StartInfo.UseShellExecute = false;
                coreprocess.StartInfo.CreateNoWindow = true;
                coreprocess.StartInfo.RedirectStandardOutput = true;
                coreprocess.StartInfo.RedirectStandardInput = true;
                coreprocess.StartInfo.FileName = installpath;
               
                // Get worker dll, currently still the main application
                string loadDLL = Directory.GetCurrentDirectory() + "\\CAD UI.dll";

                // Start Process
                this.Connected = coreprocess.Start();

                // Load worker program
                if (this.Connected)
                {
                    using (StreamWriter writer = coreprocess.StandardInput)
                    {
                        writer.WriteLine("SECURELOAD 0");
                        writer.WriteLine("NETLOAD " + loadDLL);
                        writer.WriteLine("CAD_UI");
                        writer.Close();
                    }
                }
                else
                {
                    this.coreprocess.Close();
                    this.coreprocess.Dispose();
                }
            }
            catch
            {
                this.Connected = false;

                this.coreprocess.Close();
                this.coreprocess.Dispose();
            }
        }

        #endregion
    }
}

Right now, my CAD_UI.dll holds my main program. This can obviously execute AutoCAD code as it gets loaded into AutoCAD.

What I need is to use Worker.dll instead of CAD_UI.dll
CAD_UI will open as many instances of AutoCAD as deemed necessary, and it is necessary (I want to automate electrical drawings. 50~80 drawings per panel, 50~100 panels in a facility).
I would like all of my AutoCAD code in CAD_UI and Worker.dll is simply a communication interface between CAD_UI and AutoCAD. I am using every bit I can to squeeze as much performance as possible (side databases) and the like.

MP

  • Seagull
  • Posts: 17722
  • Have thousands of dwgs to process? Contact me.
Re: Background Workers
« Reply #1 on: Today at 01:31:48 PM »
Don’t know if this helps but ... I run multiple asynchronous console workers in the background, each launched by a manager that assigns a unique sentinel file to each worker process to create and populate with execution details as applicable when the worker has completed its task. The manager stays in a polling loop, performing the equivalent of a vba doevents call each nth iteration (so AutoCAD does not appear to have died) as well as looking for the sentinel files which flag completion, updating the screen if applicable with process percentages yada. If n seconds have been exceeded for a given worker it is assumed to have stalled, and subsequent measures can be taken including aborting the “wait” for said process to complete and / or killing it if applicable. The latter isn’t incorporated yet, tho I have written lisp code to kill processes in the past.

Lift what provides idea fodder, junk the rest. Cheers.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9505
Re: Background Workers
« Reply #2 on: Today at 01:42:08 PM »
You can try poll(). Please note that my experience is in POSIX (c on unix) so I cannot be much help besides passing links and what not.

[ https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.poll?view=netcore-3.1 ]
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org