zoukankan      html  css  js  c++  java
  • NX二次开发-C#多线程技术做exe外部开发(批量导出PDF图纸例子)

    NX二次开发的内部开发模式不能做多线程,只能单线程。就好比要写一个程序创建100个块,一定要在入口函数的主线程上创建100个块,如果在开几个线程去同时创建块,那么NX就会报错挂掉。

    但是,NX二次开发的外部开发模式做好exe,在去写另一个多线程的程序,调用这个exe是可以的。

    我认为在NX里做创建特征等相关的操作,与部件导航器等需要记录特征和对象创建的,就必须要单线程。如果同时多线程创建100个块,那部件导航器的建模顺序都乱掉了,所以不能多线程。

    而做一个与上面无关的操作,还是可以的。比如:批量打印图纸,批量导出模型这些。封装成exe,应用多线程技术就可以提速很多了。

    下面的例子是先用一个线程导出20张pdf,在用四个线程导出20张pdf。我们来对比下速度。

    1.封装exe(NXC#项目)

    NX11+VS2013
    
    using System;
    using NXOpen;
    using NXOpen.UF;
    
    public class Program
    {
        // class members
        private static Session theSession;
        private static UFSession theUfSession;
        public static Program theProgram;
        public static bool isDisposeCalled;
    
        //------------------------------------------------------------------------------
        // Constructor
        //------------------------------------------------------------------------------
        public Program()
        {
            try
            {
                theSession = Session.GetSession();
                theUfSession = UFSession.GetUFSession();
                isDisposeCalled = false;
            }
            catch (NXOpen.NXException ex)
            {
                // ---- Enter your exception handling code here -----
                // UI.GetUI().NXMessageBox.Show("Message", NXMessageBox.DialogType.Error, ex.Message);
            }
        }
    
        //------------------------------------------------------------------------------
        //  Explicit Activation
        //      This entry point is used to activate the application explicitly
        //------------------------------------------------------------------------------
        public static int Main(string[] args)
        {
            int retValue = 0;
            try
            {
                theProgram = new Program();
    
                //TODO: Add your application code here 
    
                Console.WriteLine("正在导出PDF");
    
                //打开prt
                Tag PartTag = Tag.Null;
                UFPart.LoadStatus ErrorStatus = new UFPart.LoadStatus();
                theUfSession.Part.Open("D:\1.prt", out PartTag, out ErrorStatus);
    
                //导出pdf
                NXOpen.Part workPart = theSession.Parts.Work;
                NXOpen.PrintPDFBuilder printPDFBuilder1;
                printPDFBuilder1 = workPart.PlotManager.CreatePrintPdfbuilder();
                printPDFBuilder1.Scale = 1.0;
                printPDFBuilder1.Size = NXOpen.PrintPDFBuilder.SizeOption.ScaleFactor;
                printPDFBuilder1.Units = NXOpen.PrintPDFBuilder.UnitsOption.English;
                printPDFBuilder1.XDimension = 8.5;
                printPDFBuilder1.YDimension = 11.0;
                printPDFBuilder1.OutputText = NXOpen.PrintPDFBuilder.OutputTextOption.Polylines;
                printPDFBuilder1.RasterImages = true;
                NXOpen.NXObject[] sheets1 = new NXOpen.NXObject[1];
                NXOpen.Drawings.DrawingSheet drawingSheet1 = (NXOpen.Drawings.DrawingSheet)workPart.DrawingSheets.FindObject("Sheet 1");
                sheets1[0] = drawingSheet1;
                printPDFBuilder1.SourceBuilder.SetSheets(sheets1);
                printPDFBuilder1.Filename = "D:\2\" + args[0].ToString() + ".pdf";//通过main函数传入参数
                NXOpen.NXObject nXObject1;
                nXObject1 = printPDFBuilder1.Commit();
                printPDFBuilder1.Destroy();
    
                //关闭prt
                theUfSession.Part.Close(theSession.Parts.Display.Tag,1,1);
    
                theProgram.Dispose();
            }
            catch (NXOpen.NXException ex)
            {
                // ---- Enter your exception handling code here -----
    
            }
            return retValue;
        }
    
        //------------------------------------------------------------------------------
        // Following method disposes all the class members
        //------------------------------------------------------------------------------
        public void Dispose()
        {
            try
            {
                if (isDisposeCalled == false)
                {
                    //TODO: Add your application code here 
                }
                isDisposeCalled = true;
            }
            catch (NXOpen.NXException ex)
            {
                // ---- Enter your exception handling code here -----
    
            }
        }
    
    }
    
    
    Caesar卢尚宇
    2020年10月6日

    2.调用exe(C#控制台项目)

    主线程

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Threading;
    
    namespace ConsoleApplication2
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("程序开始执行
    ");
    
                System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
                watch.Start();  //开始监视代码运行时间
    
                MyCounter counter = new MyCounter();
                MyCounterA counterA = new MyCounterA();
                MyCounterB counterB = new MyCounterB();
    
                Thread t = new Thread(new ThreadStart(counter.Run));
                t.Start();
    
                Thread tA = new Thread(new ThreadStart(counterA.Run));
                tA.Start();
    
                Thread tB = new Thread(new ThreadStart(counterB.Run));
                tB.Start();
    
                for (int i = 0; i < 5; i++)
                {
                    //调用exe创建块
                    System.Diagnostics.Process exep1 = System.Diagnostics.Process.Start("D:\TestCode\NX11_Open_CS_Wizard4\NX11_Open_CS_Wizard4\bin\Debug\NX11_Open_CS_Wizard4.exe", i.ToString()+"A");
                    exep1.WaitForExit();//等待外部程序退出后才能往下执行
                }
    
                watch.Stop();  //停止监视
                TimeSpan timespan = watch.Elapsed;  //获取当前实例测量得出的总时间
                Console.WriteLine("程序结束" + ",代码执行时间:{0}(毫秒)", timespan.TotalMilliseconds);//总毫秒数
            }
        }
    }
    
    Caesar卢尚宇
    2020年10月6日

    线程1

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Threading;
    
    namespace ConsoleApplication2
    {
        class MyCounter
        {
            public void Run()
            {
                for (int i = 0; i < 5; i++)
                {
                    //调用exe创建块
                    System.Diagnostics.Process exep1 = System.Diagnostics.Process.Start("D:\TestCode\NX11_Open_CS_Wizard4\NX11_Open_CS_Wizard4\bin\Debug\NX11_Open_CS_Wizard4.exe", i.ToString() + "B");
                    exep1.WaitForExit();//等待外部程序退出后才能往下执行
                }
            }
        }
    }
    
    Caesar卢尚宇
    2020年10月6日

    线程2

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication2
    {
        class MyCounterA
        {
            public void Run()
            {
                for (int i = 0; i < 5; i++)
                {
                    //调用exe创建块
                    System.Diagnostics.Process exep1 = System.Diagnostics.Process.Start("D:\TestCode\NX11_Open_CS_Wizard4\NX11_Open_CS_Wizard4\bin\Debug\NX11_Open_CS_Wizard4.exe", i.ToString() + "C");
                    exep1.WaitForExit();//等待外部程序退出后才能往下执行
                }
            }
        }
    }
    
    Caesar卢尚宇
    2020年10月6日

    线程3

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication2
    {
        class MyCounterB
        {
            public void Run()
            {
                for (int i = 0; i < 5; i++)
                {
                    //调用exe创建块
                    System.Diagnostics.Process exep1 = System.Diagnostics.Process.Start("D:\TestCode\NX11_Open_CS_Wizard4\NX11_Open_CS_Wizard4\bin\Debug\NX11_Open_CS_Wizard4.exe", i.ToString() + "D");
                    exep1.WaitForExit();//等待外部程序退出后才能往下执行
                }
            }
        }
    }
    
    Caesar卢尚宇
    2020年10月6日

    3.速度对比动画

    1.四个线程导出20张pdf

    2.一个线程导出20张pdf

    在速度上,肉眼就已经可以看出差距了。

    4.补充

     1.想要每次调用exe不弹出控制台窗口的话,可以使用下面这种方式调用。

                for (int i = 0; i < 20; i++)
                {
                    //调用exe创建块
                    System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo("D:\TestCode\NX11_Open_CS_Wizard4\NX11_Open_CS_Wizard4\bin\Debug\NX11_Open_CS_Wizard4.exe", i.ToString()+"A");
                    //设置不在新窗口中启动新的进程
                    startInfo.CreateNoWindow = true;
                    //不使用操作系统使用的shell启动进程
                    startInfo.UseShellExecute = false;
                    //将输出信息重定向
                    startInfo.RedirectStandardOutput = true;
                    System.Diagnostics.Process process = System.Diagnostics.Process.Start(startInfo);;
                    process.WaitForExit();
                }

    2.有些调用的exe是不需要阻塞等待的,就不需要用process.WaitForExit();这句了,速度上能更快些。

    如果有些需要等调用exe,等待exe执行完的内容的,就需要阻塞等待了。等exe结束了,在执行下面的操作。

    Caesar卢尚宇

    2020年10月6日

  • 相关阅读:
    vue-cli
    使用git push命令如何忽略不想提交的文件夹或者文件
    Ajax实现的城市二级联动三
    Ajax实现的城市二级联动二
    Ajax实现的城市二级联动一
    DOM之城市二级联动
    如何把SVG小图片转换为 html字体图表
    vue权威指南笔记01——样式的设置
    2018年前端年末小结
    Array常用方法总结
  • 原文地址:https://www.cnblogs.com/nxopen2018/p/13773801.html
Copyright © 2011-2022 走看看