其他进程使用OleDB c#读取Excel文件

其他进程使用OleDB c#读取Excel文件,c#,excel,C#,Excel,我试图每隔2秒读取一个excel文件,该文件正在被其他RTD应用程序更新 我可以通过Oledb连接读取此文件,但当我尝试每2秒读取一次时,问题就出现了。在10次尝试中,它只能读取4-5次,在其他尝试中,它抛出异常 连接字符串 Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\nids\shes.xlsm;Extended Properties="Excel 12.0 Macro;HDR=Yes;IMEX=1" 代码 //opening conne

我试图每隔2秒读取一个excel文件,该文件正在被其他RTD应用程序更新

我可以通过Oledb连接读取此文件,但当我尝试每2秒读取一次时,问题就出现了。在10次尝试中,它只能读取4-5次,在其他尝试中,它抛出异常

连接字符串

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\nids\shes.xlsm;Extended Properties="Excel 12.0 Macro;HDR=Yes;IMEX=1"
代码

//opening connection to excel file

using (OleDbConnection connection = new OleDbConnection(constr))//constr = connection string
{
    try
    {  
        connection.Open();
        isconopen = true;
    }
    catch
    {
        dispatcherTimer2.Start();

        connection.Close();
        isconopen = false;
    }

    // If connection is ok , then query sheet  
    if (isconopen == true)
    {
        strcon = "SELECT * FROM [" + dsheet + "]";

        using (OleDbDataAdapter adapter = new OleDbDataAdapter(strcon, connection))
        {

            try
            {


                adapter.Fill(result);
                isread = true;
                adapter.Dispose();

                connection.Close();
            }
            catch 
            {

                isread = false;
                dispatcherTimer2.Start();

                adapter.Dispose();
                connection.Close();

            }

        }
     }

    //if able to retrieve data then call some other function 
    if (isread == true)
    {
        converToCSV(0);// for further processing
    }

请帮帮我,我从上个月开始尝试这个。请帮帮我吧

不幸的是,OleDB驱动程序在默认情况下将以独占方式打开文件,而当其他人正在使用该文件时,即使只是为了阅读,您也无法打开它

两个考虑因素:

  • 其他应用程序可能会在毫秒内完成对该文件的工作,因此最好再试一次
  • 驱动程序将始终打开锁定用于写入的文件(所以您不能通过OleDB将其打开两次),但它是共享的用于读取(所以您可以复制它)
也就是说,我建议你先尝试在短暂的停顿后打开它,如果它还在使用中(你不能再等了),那么你可以复制并打开它

假设您的代码位于
HandlExcelFile()
函数中:

void HandleExcelFile(string path)
{
    try
    {
        // Function will perform actual work
        HandleExcelFileCore(path); 
    }
    catch (Exception) // Be more specific
    {
        Thread.Sleep(100); // Arbitrary

        try
        {
            HandleExcelFileCore(path);
        }
        catch (Exception)
        {
            string tempPath = Path.GetTempFileName();
            File.Copy(path, tempPath);

            try
            {
                HandleExcelFileCore(tempPath);
            }
            finally
            {
                File.Delete(tempPath);
            }
        }
    }
}
<>代码有点丑,所以把它作为编写自己函数的起点。

考虑事项:

  • 重试并不是一件坏事,它是解决此类问题的常用方法。例如,这就是WindowsShell所做的(在网络中更为正常)
  • 如果应用程序未关闭文件,则可以复制(并读取)旧数据。如果您总是需要最新的数据,那么您只有一个选择:等待。如果您可以假设未保存的数据属于前一个时间帧(T-1,当信号边缘位于时钟边缘时,与数字电子中的T-1一样),那么只需这样做,就可以快乐地生活
未经测试的解决方案:

我没试过,所以你得自己做。实际上(最初我错了),您可以(通过扩展属性)打开只读连接。如果这仅适用于连接或同时适用于文件句柄和连接,则没有文档记录。无论如何,让我们尝试将您的连接字符串更改为:

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\nids\shes.xlsm;Extended Properties="Excel 12.0 Macro;HDR=Yes;IMEX=1;ReadOnly=true"
刚刚在扩展属性的末尾添加了一个
ReadOnly=true

其他解决办法:

  • 我想到的唯一替代方案是…手动读取Excel文件(这样您就可以打开它进行阅读)。也就是说,即使在这种情况下,另一个应用程序也可能没有写入新数据(因此您将读取旧数据)
  • 根本不用定时器。将设计更改为使用
    FileSystemWatcher
    ,只有在通知文件已更改时,才能读取该文件
  • 如果适用…请不要将共享文件用作IPC机制!嗯,您可能无法更改第二份申请,因此这可能不是您的情况
  • 不要使用OleDB读取Microsoft Excel文件,例如,有许多第三方免费库不会使用独占锁打开文件
  • 不要直接从文件中读取数据,如果Microsoft Excel实例始终在运行,则可以使用COM互操作获取通知。检查COM加载项,了解如何将带有Office Interop的C#应用程序附加到现有的Microsoft Excel实例

很遗憾,OleDB驱动程序在默认情况下将以独占方式打开文件,而当其他人正在使用该文件时,即使只是为了阅读,也无法打开该文件

两个考虑因素:

  • 其他应用程序可能会在毫秒内完成对该文件的工作,因此最好再试一次
  • 驱动程序将始终打开锁定用于写入的文件(所以您不能通过OleDB将其打开两次),但它是共享的用于读取(所以您可以复制它)
也就是说,我建议你先尝试在短暂的停顿后打开它,如果它还在使用中(你不能再等了),那么你可以复制并打开它

假设您的代码位于
HandlExcelFile()
函数中:

void HandleExcelFile(string path)
{
    try
    {
        // Function will perform actual work
        HandleExcelFileCore(path); 
    }
    catch (Exception) // Be more specific
    {
        Thread.Sleep(100); // Arbitrary

        try
        {
            HandleExcelFileCore(path);
        }
        catch (Exception)
        {
            string tempPath = Path.GetTempFileName();
            File.Copy(path, tempPath);

            try
            {
                HandleExcelFileCore(tempPath);
            }
            finally
            {
                File.Delete(tempPath);
            }
        }
    }
}
<>代码有点丑,所以把它作为编写自己函数的起点。

考虑事项:

  • 重试并不是一件坏事,它是解决此类问题的常用方法。例如,这就是WindowsShell所做的(在网络中更为正常)
  • 如果应用程序未关闭文件,则可以复制(并读取)旧数据。如果您总是需要最新的数据,那么您只有一个选择:等待。如果您可以假设未保存的数据属于前一个时间帧(T-1,当信号边缘位于时钟边缘时,与数字电子中的T-1一样),那么只需这样做,就可以快乐地生活
未经测试的解决方案:

我没试过,所以你得自己做。实际上(最初我错了),您可以(通过扩展属性)打开只读连接。如果这仅适用于连接或同时适用于文件句柄和连接,则没有文档记录。无论如何,让我们尝试将您的连接字符串更改为:

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\nids\shes.xlsm;Extended Properties="Excel 12.0 Macro;HDR=Yes;IMEX=1;ReadOnly=true"
刚刚在扩展属性的末尾添加了一个
ReadOnly=true

其他解决办法:

  • 我想到的唯一替代方案是…手动读取Excel文件(这样您就可以打开它进行阅读)。也就是说,即使在这种情况下,另一个应用程序也可能没有写入新数据(因此您将读取旧数据)
  • 根本不用定时器。将设计更改为使用
    FileSystemWatcher
    ,只有在通知文件已更改时,才能读取该文件
  • 如果适用…请不要将共享文件用作IPC机制!嗯,您可能无法更改第二份申请,因此这可能不是您的情况
  • 不要使用OleDB读取Microsoft Excel文件,例如,有许多第三方免费库不会使用独占锁打开文件
  • 不要直接从文件中读取数据,如果Microsoft Excel实例始终在运行,则可以使用COM互操作获取通知。检查COM加载项并查看如何