使用自动重置事件没有按预期工作



我是c#编程的新手,我试图实现以下结果,但未能做到。

我的期望-:在按钮的单击事件上,我想通过其API打开应用程序,运行分析,然后退出应用程序。在运行应用程序时,我在表单上有一个进度条,应该从0 - 100一直到通过API调用的RunAnalysis()方法被执行,当它被执行时,进度条应该显示为100%,通过调用的应用程序应该退出

发生了什么-:

RunanAlysis()正在执行,应用程序退出,按钮的点击事件被执行,然后进度条从0移动到100,这应该不会发生

What is my attempt

namespace trialapp
{
    public partial class Form1 : Form
    {
        AutoResetEvent obj = new AutoResetEvent(false);
        public Form1()
        {
            InitializeComponent();
        }
        ETABS2015.cSapModel SapModel;
        System.Reflection.Assembly ETABSAssembly;
        ETABS2015.cOAPI ETABSObject;
        int result = -1;
        delegate int MyDelegate();
        MyDelegate pointer = null;
        private void button1_Click(object sender, EventArgs e)
        {
            //Use ret to check return values of OAPI calls 
            int ret;
            //Dynamically load ETABS.exe assembly from the program installation folder 
            string pathToETABS = System.IO.Path.Combine(Environment.GetEnvironmentVariable("PROGRAMFILES"), "Computers and Structures", "ETABS 2013", "ETABS.exe");
            ETABSAssembly = System.Reflection.Assembly.LoadFrom(pathToETABS);
            //Create an instance of ETABSObject and get a reference to cOAPI interface
            ETABSObject = (ETABS2015.cOAPI)ETABSAssembly.CreateInstance("CSI.ETABS.API.ETABSObject");
            //Start ETABS application
            ret = ETABSObject.ApplicationStart();
            //Get a reference to cSapModel to access all OAPI classes and functions
            SapModel = ETABSObject.SapModel;
            //Initialize model
            ret = SapModel.InitializeNewModel();
            //Create steel deck template model
            ret = SapModel.File.NewSteelDeck(4, 12, 12, 4, 4, 24, 24);
            //Save model
            System.IO.Directory.CreateDirectory("C:\ETABSAPI");
            ret = SapModel.File.Save("C:\ETABSAPI\example2.edb");
            //Run analysis
            backgroundWorker1.RunWorkerAsync();
           // ret = SapModel.Analyze.RunAnalysis();

            obj.WaitOne();
            //Close ETABS
            ret = ETABSObject.ApplicationExit(false);
            //Clean up variables
            SapModel = null;
            ETABSObject = null;
            //Check ret value 
            if (ret == 0)
            {
                MessageBox.Show("API script completed succesfully.");
            }
            else
            {
                MessageBox.Show("API script FAILED to complete.");
            }
        }
        public void AfterRunAnalysisComplete(IAsyncResult resultHolder)
        {
            result = pointer.EndInvoke(resultHolder);
        }
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            pointer = new MyDelegate(SapModel.Analyze.RunAnalysis);
            IAsyncResult flag = pointer.BeginInvoke(new AsyncCallback(AfterRunAnalysisComplete), null);
            while (!flag.IsCompleted)
            {
                for (int i = 0; i <= 100; i++)
                {
                    Thread.Sleep(100);
                    backgroundWorker1.ReportProgress(i);
                    if (i == 100)
                    {
                        i = 0;
                    }
                    if (flag.IsCompleted)
                    {
                        break;
                    }
                }
            }
            backgroundWorker1.ReportProgress(100);
            //obj.Set();

        }
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }
    }
}

谁能告诉我到底哪里错了?

编辑-:

我尝试不使用WaitOne()并将backgroundWorker1.RunWorkerAsync();之后的代码放在backgroundWorker1_DoWork方法中,但这不是我想做的,因为主要项目的范围太大,这对类的设计没有意义。

问题在于当你启动

ret = ETABSObject.ApplicationStart();

,它将在一个新的线程中启动它,这个线程是你的程序无法访问的。我建议在TaskFactory中启动应用程序,然后你可以用一段时间来检查任务是否仍在运行并更新进度条。

也许像这样:

var etabApp = Task.Factory.Startnew(() => { ETABSObject.ApplicationStart()});
while(etabApp.Status == TaskStatus.Running)
{
   //Do something to check the percent complete and update the progress bar
}

相关内容

  • 没有找到相关文章

最新更新