我在Solidworks插件中有一些函数,该函数调用一个同事在过去几周中一直在研究的VBA宏(通过runMacro2方法)。在他的代码中,他调用了Solidworks函数,该函数在某些未知情况下会长时间挂起。似乎要多长时间取决于零件中物体的大小和数量。考虑到我们要从i自动运行此功能的至少一项功能,这只是做不到的。
我尝试使用Thread.Join(int)方法(如下所示),但是它不起作用。我还尝试修改此答案Close a MessageBox after several seconds中的代码,结果相同。我可以在C#或VBA中做任何事情来处理超时而无需重写他的整个宏吗?
public void runBB()
{
Stopwatch testStop = new Stopwatch();
Thread workerThread = new Thread(bbRun);
testStop.Start();
workerThread.Start();
if (!workerThread.Join(50))
{
workerThread.Abort();
testStop.Stop();
MessageBox.Show("Unable to generate Bounding Box after " + testStop.ElapsedMilliseconds/1000 + " seconds. Please enter data manually.", "Solidworks Derped Error.");
}
return;
}//Still uses Macro (2-5-16)
public static void bbRun()
{
iSwApp.RunMacro2(macroPath + "BOUNDING_BOX.swp", "test11", "main", 0, out runMacroError);
return;
}
最佳答案
SOLIDWORKS挂在打开的文件上时,我也遇到了同样的问题。关于SO的几乎所有参考都是您永远不要这样做,但是在这种情况下,您要么必须关闭它,要么永远等待。在C#中,我创建了一个callWithTimeout方法:
private void callWithTimeout(Action action, int timeoutMilliseconds, String errorText) {
Thread threadToKill = null;
Action wrappedAction = () =>
{
threadToKill = Thread.CurrentThread;
action();
};
IAsyncResult result = wrappedAction.BeginInvoke(null, null);
if (result.AsyncWaitHandle.WaitOne(timeoutMilliseconds)) {
wrappedAction.EndInvoke(result);
} else {
threadToKill.Abort();
throw new TimeoutException(errorText);
}
}
然后将挂起的代码放在这样的块中:
bool timedOut = false;
try {
callWithTimeout(delegate() {
// code that hangs here
}, 60000, "Operation timed out. SOLIDWORKS could not open the file. This file will be processed later.");
} catch (TimeoutException){
timedOut = true;
} finally {
if(timedOut) {
Process[] prs = Process.GetProcesses();
foreach (Process p in prs) {
if (p?.ProcessName.Equals("SLDWORKS") ?? false)
p?.Kill();
}
}
}