C# 使用自动重置事件未按预期工作

C# 使用自动重置事件未按预期工作,c#,winforms,.net-4.5,C#,Winforms,.net 4.5,我对c#编程相当陌生,我正在尝试实现以下结果,但未能实现 我的期望-: 在按钮的单击事件中,我希望通过其API打开应用程序,运行分析,然后退出应用程序。在运行应用程序时,我在表单上有一个进度条,它应该从0到100一直运行,直到通过API调用的RunAnalysis()方法被执行,当它被执行时,进度条应该显示为100%,通过调用的应用程序应该退出 发生了什么-: 正在执行RunanAlysis(),应用程序退出,执行按钮的单击事件,然后进度条从0移动到100,这是不应该发生的 我的尝试是什么 na

我对c#编程相当陌生,我正在尝试实现以下结果,但未能实现

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

发生了什么-:

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

我的尝试是什么

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;
        }
    }
}
namespace-trialapp
{
公共部分类Form1:Form
{
AutoResetEvent obj=新的AutoResetEvent(假);
公共表格1()
{
初始化组件();
}
ETABS2015.cSapModel-SapModel;
系统.反射.装配ETabassembly;
ETABS2015.cOAPI ETABSObject;
int结果=-1;
delegate int MyDelegate();
MyDelegate指针=null;
私有无效按钮1\u单击(对象发送者,事件参数e)
{
//使用ret检查OAPI调用的返回值
int ret;
//从程序安装文件夹动态加载ETABS.exe程序集
字符串pathtoetab=System.IO.Path.Combine(Environment.GetEnvironmentVariable(“PROGRAMFILES”)、“计算机和结构”、“ETABS 2013”、“ETABS.exe”);
ETABSAssembly=System.Reflection.Assembly.LoadFrom(路径到选项卡);
//创建ETABSObject的实例并获取对cOAPI接口的引用
ETABSObject=(ETABS2015.cOAPI)etabassembly.CreateInstance(“CSI.ETABS.API.ETABSObject”);
//启动ETABS应用程序
ret=ETABSObject.ApplicationStart();
//获取对cSapModel的引用以访问所有OAPI类和函数
SapModel=ETABSObject.SapModel;
//初始化模型
ret=SapModel.InitializeNewModel();
//创建钢桥面模板模型
ret=SapModel.File.NewSteelDeck(4,12,12,4,4,24,24);
//保存模型
System.IO.Directory.CreateDirectory(“C:\\ETABSAPI”);
ret=SapModel.File.Save(“C:\\ETABSAPI\\example2.edb”);
//运行分析
backgroundWorker1.RunWorkerAsync();
//ret=SapModel.Analyze.RunAnalysis();
obj.WaitOne();
//关闭ETAB
ret=ETABSObject.ApplicationExit(false);
//清理变量
SapModel=null;
ETABSObject=null;
//检查ret值
如果(ret==0)
{
Show(“API脚本成功完成”);
}
其他的
{
Show(“API脚本未能完成”);
}
}
运行分析完成后公共无效(IAsyncResult resultHolder)
{
结果=指针.EndInvoke(resultHolder);
}
私有void backgroundWorker1\u DoWork(对象发送方,DoWorkEventArgs e)
{
指针=新的MyDelegate(SapModel.Analyze.RunAnalysis);
IAsyncResult flag=pointer.BeginInvoke(新的异步回调(AfterRunAnalysisComplete),null);
而(!flag.IsCompleted)
{

对于(inti=0;i,在我看来,问题在于你什么时候开始

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
}

当您的代码出现特定问题时,请创建一个最小的工作示例来说明问题。问题是,当我阅读您的代码时,我只能判断它看起来正常。但这并不意味着什么。我无法尝试您的代码,因为我不知道您在反射代码或硬盘上的文件中使用的类。据我所知,
WaitOne()
应该永远被阻止,因为
Set()
被注释掉了。我已经尝试过Set(),但它不起作用。另外,我希望问题尽可能清楚,但我不确定哪一部分对正在研究它的人来说是至关重要的。那么,我很抱歉,但无法帮助你。那么,当你有Set()时它取消了对调用方的阻止,因此退出了应用程序。从代码中,当标志设置为完成时,会发生这种情况,因此您需要了解…标志设置为完成的时间点是什么导致它从while循环和调用集()中断的这反过来会退出应用程序。对我来说,它工作正常,但您的逻辑可能不正确:)