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