Gentlemen,
I have found a way to run the AutoCAD Core Console with the window invisible, set secureload to 0, then Netload a dll, run a .NET Lisp application with an argument, a GUID string. This string is the pipe name for inter process communication. This allows external applications to process dwgs elegantly.
The AutoCAD Core Console itself uses very little RAM in comparison to AutoCAD. When it is idling it uses 0% CPU power. The problem I am running into is that my application is hogging a lot of CPU power. I have 10 cores, 20 threads in my intel I9 CPU. It is using one thread at 100%, or 5% of an entire CPU. I want to reduce this to ~0.1% when the program is idling.
The following is my code that runs in the AutoCAD Core Console.
using AcConsole;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Clifton.Core.Pipes;
using NetDBX;
using System.Collections.Generic;
using System.IO;
namespace AcConsoleIn
{
/// <summary>
/// Provides static methods to run within AutoCAD Core Console
/// </summary>
public static class Run
{
// IPC Pipe
private static ClientPipe Client { get; set; }
/// <summary>
/// Provides the Lisp Function to connect this process to an external application.
/// </summary>
/// <param name="buffer"></param>
[LispFunction("PROCESS")]
public static void Process(ResultBuffer buffer)
{
try
{
using (buffer)
{
// Process input
List<TypedValue> args = AutoLisp.HandleLispArguments(buffer, 1, 1);
// Create and connect IPC pipe
string pipeName = AutoLisp.LispToString(args[0]);
Client = new ClientPipe(".", pipeName, p => p.StartStringReaderAsync());
Client.DataReceived += Client_DataReceived;
Client.Connect();
}
}
catch { }
}
/// <summary>
/// Event Handler for processing data from server.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void Client_DataReceived(object sender, PipeEventArgs e)
{
// Exit if communication pipe is broken
if (Client == null)
return;
try
{
// Check for a close application message
if (e.String == "Close Application")
{
// Disconnect Pipe
Client.DataReceived -= Client_DataReceived;
Client.Close();
Client = null;
// Close AutoCAD
Autodesk.AutoCAD.ApplicationServices.Core.Application.Quit();
return;
}
// Tell server that this is busy
Client.WriteString("1");
// Get database object
AcConsole.DatabaseServices.Database database;
database = IO.XmlDeserializeFromString<AcConsole.DatabaseServices.Database>(e.String);
// Throw error if it received an invalid database object
if (database == null)
throw new InvalidDataException("Invalid Database Object");
// Create new drawing
using Database drawing = new Database(true, true);
using (Transaction transaction = drawing.TransactionManager.StartTransaction())
{
// Convert AcConsole.DatabaseServices.Database to Autodesk.AutoCAD.DatabaseServices.Database
database.ToDatabase(drawing, transaction);
transaction.Commit();
}
// Delete file if it exists
string filename = database.Filename;
if (File.Exists(filename))
File.Delete(filename);
// Save drawing
drawing.SaveAs(filename, DwgVersion.Current);
// Tell Server it is not busy.
Client.WriteString("0");
}
catch (System.Exception ex)
{
// Tell server that an error occured.
Client.WriteString(ex.Message);
}
}
}
}
I thought if I use an event handler, I would not use any CPU power when it is idling. Could anyone help me out?