我对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;
}
}
}
任何人都可以告诉我出错的地方吗?
修改 - :
我尝试不使用WaitOne()
并在backgroundWorker1.RunWorkerAsync();
方法中放置backgroundWorker1_DoWork
后面的代码,但这不是我想做的,因为主要项目的范围太大而且这对于类的设计没有意义。
答案 0 :(得分:0)
正如我所看到的那样,问题在于你何时开始
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
}