Virendra S from Bangalore, Karnataka Ответов: 1

Процесс не может получить доступ к файлу xyzfilename.xls потому что он используется другим процессом


Я создаю консольное приложение, которое запускает почту с некоторыми данными.
я получаю нижеприведенную ошибку в методе "WriteToExcel".
"Процесс не может получить доступ к файлу xyzfilename.xls потому что он используется другим процессом".

пожалуйста, выясните причину ошибки и предложите soln.

class Program
{
static void Main(string[] args)
{dtResultInvoices = objBL.InvoicesDetailsBL();
 Mailcontent(dtResultInvoices);
}
}
 public static void Mailcontent(DataTable dtResultInvoices)
{// some code to build mail body with foreach (DataRow row in table.Rows)--

 Helper.WriteToExcel(dtdistinctinvoices); ---- table dtdistinctinvoices created from dtResultInvoices with some filter operations.
 Helper.Sendmail(strmailfrom, strmailto, strmailsubject, Mailcontent.ToString(), strmailcc, null, Helper.attachments); 
}




class Helper
{
 public static void Sendmail(string mailFrom, string toMail, string mailSubject, string mailBody, string mailCC, string mailBcc, List<string> MailAttach)
{
}
 public static void WriteToExcel(DataTable Dtattach)
        {
            DataTable dtCopy = new DataTable();
            try
            {
                StringBuilder builder = new StringBuilder();
        
                if (Dtattach != null && Dtattach.Rows.Count > 0)
                {
                    dtCopy = Dtattach.Copy();
       
                    // Create physical path to store the files                  
                    string Savepath = ConfigurationManager.AppSettings["MailPath"].ToString() + "\\";
                 
                    // check already this directory exists or not
                    if (!Directory.Exists(Savepath))
                    {
                        Directory.CreateDirectory(Savepath);
                    }
                    Savepath = Savepath + "xyzfilename.xls";
                    FileInfo TheFile = new FileInfo(Savepath);

                    if (TheFile.Exists && (!IsFileLocked(TheFile))) 
                    {
                        File.Delete(TheFile.FullName);
                    }
                                      
                    using (ExcelPackage objExcelPackage = new ExcelPackage())
                    {
                        ExcelWorksheet objWorksheet = objExcelPackage.Workbook.Worksheets.Add("AllocatedDetails");
                        objWorksheet.Cells["A1"].LoadFromDataTable(dtCopy, true);
                        objWorksheet.Protection.AllowDeleteRows = true;
                        objWorksheet.Protection.AllowAutoFilter = true;
                        objWorksheet.Protection.AllowFormatCells = true;
                        objWorksheet.Protection.AllowSort = true; objWorksheet.Cells.AutoFitColumns();
                        objWorksheet.Cells["A1:M1"].AutoFilter = true;
                        using (ExcelRange objRange = objWorksheet.Cells["A1:M1"])
                        {
                            objRange.Style.Font.Bold = true;
                            objRange.Style.Font.Color.SetColor(Color.White);
                            objRange.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                            objRange.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                            objRange.Style.Fill.PatternType = ExcelFillStyle.Solid;
                            objRange.Style.Fill.BackgroundColor.SetColor(Color.ForestGreen);
                            objRange.Style.Locked = true;
                        }
                        FileStream objFileStrm = File.Create(Savepath);
                        objFileStrm.Close(); File.WriteAllBytes(Savepath, objExcelPackage.GetAsByteArray());
                        objFileStrm.Dispose();
                    }
                    attachments.Clear();
                    attachments.Add(Savepath);
                    //System.Threading.Thread.Sleep(9000); ---------tried this, thread sleep some times works fine,but failing when huge number of records in the table
                }
               
            }
            catch (Exception Ex)
            {
               
            }
        }      
}


Что я уже пробовал:

public static Boolean IsFileLocked(FileInfo file)
       {
           FileStream stream = null;

           try
           {
               //Don't change FileAccess to ReadWrite,
               //because if a file is in readOnly, it fails.
               stream = file.Open
               (
                   FileMode.Open,
                   FileAccess.Read,
                   FileShare.None
               );
           }
           catch (IOException)
           {
               //the file is unavailable because it is:
               //still being written to
               //or being processed by another thread
               //or does not exist (has already been processed)
               return true;
           }
           finally
           {
               if (stream != null)
                   stream.Close();
           }

           //file is not locked
           return false;
       }



попробовал с помощью
System.Threading.Thread.Sleep(9000)
но не работает.

F-ES Sitecore

Какая строка вызывает ошибку?

Virendra S from Bangalore, Karnataka

Я не уверен в этом, но иногда код проходит через внутреннее условие if (true,когда файл не заблокирован), а иногда и нет (false)
если (файл.Существует && (!IsFileLocked(TheFile)))
{
Файл.Удалить(Файл.Полное имя);


Не понимая, в каком процессе файл все еще доступен/открыт.

}

Afzaal Ahmad Zeeshan

Скорее всего, ваш файл в данный момент открыт в одном из ваших собственных процессов, в этом самом процессе, или, скорее всего, в фоновом режиме. Кто знает?

Кроме того, вы проверяете, существует ли файл, а затем в последующих разделах вы "создаете" файл, а затем закрываете поток и записываете в него с помощью вспомогательных методов. В чем именно заключается это требование?

CHill60

Пожалуйста, перестаньте думать, что просто Спящая нить решит все. А если вы настаиваете на проглатывании ошибок, используя

catch (Exception Ex)
{
}
тогда вы никогда не узнаете, в чем заключаются настоящие проблемы.

1 Ответов

Рейтинг:
5

Dave Kreskowiak

Как говорится в ошибке, файл либо открыт в другом процессе, либо в вашем собственном процессе, где вы, возможно, читали его и забыли закрыть файл, прежде чем пытаться открыть его снова для операции записи.

Как уже говорили другие, вызов Sleep вообще ничего не решает, а перехват исключений и отсутствие каких-либо действий с ними просто скрывают проблемы, с которыми сталкивается ваш код.

Сказав это, ваш код проверяет функцию под названием "IsFileLocked", но проблема с этой функцией заключается в том, что при ее запуске файл может быть доступен, но всего через миллисекунды его может и не быть.

Перед созданием книги Excel необходимо проверить, заблокирован ли файл. Ладно, ладно. Но тогда ваш код занимает, скажем, 10 секунд, чтобы построить книгу, прежде чем пытаться записать ее в файл. Ну, вы проверили, что файл был заблокирован 10 секунд назад. Результат этого теста ничего не значит только через миллисекунды после того, как вы выполнили этот тест.