我有一个使用office互操作库(Word和Excel 2007)库版本12.0的应用程序,我有一个通用的方法来执行超时的任务,以防Office由于某种原因停止响应但是当方法返回其值时它会抛出一个例外,说明与其rcw分离时无法使用Com对象。
方式:
public static R ExecuteOfficeTimoutAction<R>(Func<R> ToExecute, TimeSpan TimeOut)
{
object returnVal = new OfficeEmptyReturn(); // Empty Class Used With Reflection To Tell If There Was Really A Value Returned
try
{
Exception threadError = null;
System.Threading.Thread timedThread = new System.Threading.Thread(() =>
{
try
{
returnVal = ToExecute();
}
catch (Exception ex)
{
threadError = ex;
}
});
timedThread.Priority = System.Threading.ThreadPriority.Normal;
timedThread.SetApartmentState(System.Threading.ApartmentState.STA);
timedThread.Start();
timedThread.Join(TimeOut);
if (threadError != null)
{
throw threadError;
}
if (timedThread.ThreadState != System.Threading.ThreadState.Stopped)
{
bool abortCalled = false;
bool processKilled = false;
int waitTime = 0;
do
{
if (!abortCalled)
{
timedThread.Abort();
abortCalled = true;
}
if (waitTime < 2500)
{
waitTime += 250;
System.Threading.Thread.Sleep(250);
}
else if (!processKilled)
{
processKilled = true;
foreach (System.Diagnostics.Process process in System.Diagnostics.Process.GetProcesses())
{
if (process.ProcessName.ToLower().Contains("winword.exe") || process.ProcessName.ToLower().Contains("excel.exe"))
{
process.Close();
}
}
}
else
{
throw new TimeoutException("The Timeout Action Could Not Be Terminated");
}
}
while (!(timedThread.ThreadState == System.Threading.ThreadState.Aborted || timedThread.ThreadState == System.Threading.ThreadState.Stopped));
}
}
catch (Exception)
{
throw;
}
return (R)returnVal; // Throws Exception Here
}
引发错误的方法:
public Document GetDocument(string FilePath)
{
Document newDoc = null;
if (!String.IsNullOrWhiteSpace(FilePath))
{
if (File.Exists(FilePath) && IsWordDoc(new FileInfo(FilePath)))
{
if (IsActive)
{
if (FilePath.Length < 255)
{
newDoc = ExecuteOfficeTimoutAction<Application, Document>((Application app) =>
{
Document tempDoc = app.Documents.Open(FilePath, Type.Missing, true);
return tempDoc;
}, App, new TimeSpan(0, 0, 10));
if (newDoc == null || newDoc is OfficeEmptyReturn)
{
newDoc = null;
}
}
else
{
throw new ArgumentOutOfRangeException("The Word Document's Full Path Must Be Shorter Than 255 Characters To Be Reached");
}
}
else
{
throw new InvalidOperationException("The Word Application Must Be Open To Process Word Data");
}
}
else
{
throw new FileNotFoundException("The Word File Did Not Exist At The Specified Path");
}
}
else
{
throw new ArgumentNullException("The File Path Was Null");
}
return newDoc;
}
传入的App对象是一个静态Word.Application
对象,存储在包含的单词类中的一个字段中,以便所有适用的方法都可以看到它,并在不再需要时适当处理。
我不明白为什么它会在返回一个值时给出这个异常,即使它是一个com对象。
我希望的结果是方法返回传递的Func生成的值,抛出所述委托生成的异常或返回OfficeEmptyReturn。
非常感谢任何帮助或指示。
旁注,我确实有办法应用程序在应用程序自动化之外终止办公应用程序时的后备错误处理,我会打开任务管理器并在冻结我的代码时手动终止单词然后它会继续但这是不可接受的结果