C#的Excel互操作 - 如何测试是否互操作对象仍然是工作,执行任务? [英] C# Excel interop - how to test if interop object is still working and performing a task?

查看:285
本文介绍了C#的Excel互操作 - 如何测试是否互操作对象仍然是工作,执行任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过几个hundered Excel文件的目录循环,并试图刷新Excel文件一次。我不断收到此错误表明该刷新操作上依然文件运行,例如,和FILEB正在试图启动刷新操作。循环是快速并不知我不得不等待之前刷新操作的文件开始刷新文件B之前完成。




未处理的异常信息:System.Runtime.InteropServices.COMException:在
消息过滤器显示应用程序正忙。 (异常来自
HRESULT:0x8001010A(RPC_E_SERVERCALL_RETRYLATER))在
Microsoft.Office.Interop.Excel._Workbook.RefreshAll()在
RefreshExcelFiles.Program.RefreshFile(字符串文件名)




下面是我的代码。我怎么能等待刷新操作,以开始处理在循环一个新的文件之前完成? ?或者,等待元帅释放操作世界银行对象上开始一个新的文件之前完成

 使用系统; 
使用System.Configuration;
:使用System.IO;使用System.Runtime.InteropServices
;
使用的Microsoft.Office.Interop.Excel;

命名空间RefreshExcelFiles
{
内部类节目
{
私人静态字符串_fileDirectory;
私有静态应用_excelApp;

私有静态无效的主要(字串[] args)
{
_fileDirectory = ConfigurationManager.AppSettings [文件目录];
_excelApp =新的应用程序();
_excelApp.DisplayAlerts = FALSE;

Console.WriteLine(开始刷新文件);
INT I = 0;
INT总= Directory.GetFiles(_fileDirectory)。长度;

的foreach(在Directory.GetFiles(字符串文件_fileDirectory))
{
I + = 1;
Console.WriteLine(文件+文件++ i.ToString()+/+ total.ToString());
RefreshFile(文件);
}

_excelApp.Quit();
Marshal.FinalReleaseComObject(_excelApp);

Console.WriteLine(按任意键退出);
到Console.ReadLine();
}

私有静态无效RefreshFile(字符串文件名)
{
_Workbook WB = _excelApp.Workbooks.Open(文件名,FALSE);
wb.RefreshAll();

wb.Save();
wb.Close(Type.Missing,Type.Missing,Type.Missing);

Marshal.FinalReleaseComObject(WB);
}
}
}


解决方案

我找到了答案,以我的问题。我需要实现IMessageFilter RetryRejectedCall 。对于C#和使用IMessageFilter :: RetryRejectedCall,的看到这个博客帖子



如果你不注册的MessageFilter自己(通过调用CoRegisterMessageFilter),你会得到这将是它是否
被拒绝失败的呼叫默认行为。 .NET中的失败HRESULT转换为例外。为了应对服务器忙时您尝试调用的可能性,就需要
实现IMessageFilter :: RetryRejectedCall在客户端代码和注册邮件过滤器。在大多数情况下,你只需要等待
A几秒钟,然后重试呼叫 - 通常这将是足够的时间来让Word来完成不管它是这样做的,它可以处理你的电话


I am looping through a directory of several hundered excel files and trying to refresh the excel files one at a time. I keep getting this error which indicates that the refresh operation is still running on File A, for example, and FileB is trying to start a refresh operation. The loop is to fast and somehow I have to wait for the prior refresh operation on File A to complete before starting to refresh File B.

Unhandled Exception: System.Runtime.InteropServices.COMException: The message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER)) at Microsoft.Office.Interop.Excel._Workbook.RefreshAll() at RefreshExcelFiles.Program.RefreshFile(String fileName)

Here is my code. How can I wait for the refresh operation to complete before starting to process a new file in the loop? Or, wait for the marshal release operation on the wb object to complete before starting on a new file?

using System;
using System.Configuration;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Excel;

namespace RefreshExcelFiles
{
    internal class Program
    {
        private static string _fileDirectory;
        private static Application _excelApp;

        private static void Main(string[] args)
        {
            _fileDirectory = ConfigurationManager.AppSettings["FileDirectory"];
            _excelApp = new Application();
            _excelApp.DisplayAlerts = false;

            Console.WriteLine("starting to refresh files");
            int i = 0;
            int total = Directory.GetFiles(_fileDirectory).Length;

            foreach (string file in Directory.GetFiles(_fileDirectory))
            {
                i += 1;
                Console.WriteLine("File " + file + " " + i.ToString() + "/" + total.ToString());
                RefreshFile(file);
            }

            _excelApp.Quit();
            Marshal.FinalReleaseComObject(_excelApp);

            Console.WriteLine("press any key to exit");
            Console.ReadLine();
        }

        private static void RefreshFile(string fileName)
        {
            _Workbook wb = _excelApp.Workbooks.Open(fileName, false);
            wb.RefreshAll();

            wb.Save();
            wb.Close(Type.Missing, Type.Missing, Type.Missing);

            Marshal.FinalReleaseComObject(wb);
        }
    }
}

解决方案

I found an answer to my problem. I needed to implement IMessageFilter RetryRejectedCall. For a C# and VB.NET code sample of using IMessageFilter::RetryRejectedCall, see this blog post.

If you don't register a MessageFilter yourself (by calling CoRegisterMessageFilter), you will get default behavior which will be to fail the call if it gets rejected.  .Net converts the failure HRESULT to an exception.  To deal with the possibility of the server being busy when you try to call, you need to implement IMessageFilter::RetryRejectedCall in your client code and also register the message filter.  In most cases, you will just need to wait for a few seconds and then retry the call--generally that will be sufficient time to enable Word to finish whatever it is doing so it can handle your call.

这篇关于C#的Excel互操作 - 如何测试是否互操作对象仍然是工作,执行任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆