1. Имеется грид, в котором пользователь может выбрать несколько строк
2. Имеется список шаблонов документов и кнопка с обработчиком на JavaScript
3. Используются сконвертированные в XML шаблоны Excel и XmlDocument для их обработки
4. Разработана форма для отчета, которая запускается через скрипт в цикле для каждой выбранной строки в гриде. в Page_Load производится рендеринг XML-данных для клиента, на котором запускается Excel
...
this.Response.ContentType = "application/vnd.ms-excel";
this.Response.AddHeader("Content-Disposition", "inline; filename=" + fileName);
...
При одновременном октрытии 1 или 2 экземпляров, все работает. При 3 экземплярах работает нестабильно, далее возникают стабильные ошибки типа "Не найден файл" (хотя файл создан и находится во временном каталоге) или "Нельзя одновременно открыть несколько форм".
Делался таймаут, attachment, синхронизация по состоянию окна (ожидание closed), уникальное определение имен окон и файлов — не помогает.
Также на некоторых шаблонах возникают проблемы с encoding — некоторые экземпляры только этих шаблонах почему-то генерируются некорректно. Стандартно используется UTF8, прописанный также в конфиге.
Здравствуйте, minyurov, Вы писали:
M>При одновременном октрытии 1 или 2 экземпляров, все работает. При 3 экземплярах работает нестабильно, далее возникают стабильные ошибки типа "Не найден файл" (хотя файл создан и находится во временном каталоге) или "Нельзя одновременно открыть несколько форм".
Общие рекомендации
— Св-ва Interactive и DisplayAlerts установить в False
— Не "бросать" ссылки на объекты, возвращаемые екселем!
Неправильно:
app.Workbooks[1].Worksheets[1].Range["A1"].Value = "aaa";
Правильно:
Workbooks books = null;
Workbook book = null;
try
{
books = app.Workbooks;
book = books[1];
}
finally
{
if (book != null) Marshal.ReleaseComObject(book);
if (books != null) Marshal.ReleaseComObject(books);
// Опционально вызвать GC.Collect();
}
— Явно закрывать приложение примерно так:
finally
{
app.Quit();
Marshal.ReleaseComObject(app);
GC.WaitForPendingFinalizers();
GC.Collect();
}
— Максимально в коде использовать примитивы синхронизации для гарантии того, чтобы exe-север не дергали за вымя несколько потоков.
— Вообще по возможности отказаться от екселя и использовать Reporting Service или какой-нибудь класс, умеющий работать с Biff (например, Component One C1Excel)