Страница 1 из 1

Выгрузка отчета

Добавлено: 30 дек 2006, 11:42
smartyn
Добрый день!
В процессе работы моей программы программно создаються домены приложения, может создаться один домен а может десяток. В некоторых доменах загружается откомпилированый отчет, выполняется рендеринг и экспорт.
Затем в какой-то момент програма решает выгрузить домен. и тут возникает проблема, домен не выгружается. попробывал убрать загрузку отчетов - все работает.
На сколько я понял отчет запускается в дополнительном домене.
Подскажите пожалуйста есть ли какая то функция которая бы корректно выгружала отчет

С уважением.

Выгрузка отчета

Добавлено: 02 янв 2007, 05:16
Vital
Дополнительные домены генератором отчетов не создаются в процессе работы.
Т.к. отчеты грузятся из откомпилированных сборок никаких дополнитеьных сборок не создается.
Трудно что-то сказать не посмотрев на Ваш код. Нужна дополнительная информация.

Спасибо.

Выгрузка отчета

Добавлено: 02 янв 2007, 06:41
smartyn
Вот исходный код класса который выполняет загрузку и запуск на экспорт отчет

Код: Выделить всё

    class umtsScriptHelper : ctScriptHelper
    {
        public umtsScriptHelper(AppDomain inDomain, string inPath, string inSrcPath, List inAutoTypes)
            : base(inDomain, inPath, inSrcPath, inAutoTypes)
        {
        }
        public override List requestAssembly(string assemblyName)
        {
            return umtsHelper.loadScriptBodies(assemblyName);
        }
        public override bool isAssemblyNeedRequest(string assemblyName)
        {
            return assemblyName.EndsWith("_exe");
        }
        public override void customFinalize()
        {
            if (report != null)
            {
                report.ClearAllStates();
                report.Clear();
                report.Dispose();
                report = null;
            }
            if (String.IsNullOrEmpty(reportFileName) == false && File.Exists(reportFileName) == true)
            {
                try
                {
                    File.Delete(reportFileName);
                }
                catch { }
            }
        }
        protected StiReport report = null;
        protected string reportFileName = "";
        public void addReport(byte[] body)
        {
            if (report != null)
            {
                report.Dispose();
                report = null;
            }
            if (String.IsNullOrEmpty(reportFileName) == false && File.Exists(reportFileName) == true)
            {
                try
                {
                    File.Delete(reportFileName);
                }
                catch { }
            }
            //reportFileName = resolvePath + "\\" + DateTime.Now.Ticks.ToString() + "__report.dll";
            //File.WriteAllBytes(reportFileName, body);
            //report = StiReport.GetReportFromAssembly(reportFileName, false);
            report = StiReport.GetReportFromAssembly(body);
        }
        public byte[] executeReport(string exportFormat, ctParamManager inParams, ref List messages)
        {
            byte[] result = null;
            if (report != null)
            {
                ctParamManager outParams = new ctParamManager();
                executeAssemblies(inParams, ref outParams, ref messages);

                StiExportFormat format = StiExportFormat.Excel;
                if (format != StiExportFormat.None)
                {
                    List names = outParams.Names;
                    foreach (string name in names)
                        report.RegData(name, outParams.GetData(name, null));
                    report.Render(false);
                    MemoryStream writer = new MemoryStream();
                    report.ExportDocument(format, writer);
                    result = writer.ToArray();
                    writer.Close();
                    writer.Dispose();
                    writer = null;
                }
            }
            return result;
        }
    }
Этот класс создается в отдельном домене. Если не происходит вызова addReport то домен выгружается нормально. Если же происходит создание экземпляра класса то выгрузить домен не получается

Выгрузка отчета

Добавлено: 02 янв 2007, 07:51
smartyn
Может Вы подскажите как у Вас реализована загрузка сборки. Интересует следующее, Вы загружаете сборку в текущий домен или домен по умолчанию?

Выгрузка отчета

Добавлено: 02 янв 2007, 11:04
Vital
Вот код для загрузки отчета из массива байтов:

Код: Выделить всё

public static StiReport GetReportFromAssembly(byte[] bytes)
		{
			MemoryStream stream  = new MemoryStream(bytes);
			StiReport report = GetReportFromAssembly(stream);
			stream.Close();
			return report;
		}


public static StiReport GetReportFromAssembly(Stream assemblyStream)
		{
			try
			{
				byte[] bytes = new Byte[assemblyStream.Length];
				assemblyStream.Seek(0, SeekOrigin.Begin);
				assemblyStream.Read(bytes, 0, (int)assemblyStream.Length);
				[b]Assembly a = Assembly.Load(bytes);[/b]
	
				return GetReportsFromAssembly(a)[0];
			}
			catch (Exception e)
			{
				StiLogService.Write(typeof(StiReport), "Get report from assembly...ERROR");
				StiLogService.Write(typeof(StiReport), e);

				if (!StiReport.HideExceptions)throw;
			}
			return null;
		}
Собственно сборка грузится методом Assembly.Load. Данный метод загружает сборку в домен, из которго был вызван этот метод.


Выгрузка отчета

Добавлено: 02 фев 2007, 03:45
Vital
Если проблема все еще не решена, то Вы можете сделать небольшое тестовое приложение, которое будет явно показывать проблему и прислать нам. Мы разберемся и поможем.

Спасибо.

Выгрузка отчета

Добавлено: 05 фев 2007, 11:56
smartyn
Попробывал локализовать проблему. Похоже какаято связка моей программы и Вашей компоненты приводит к этой ситуации. Я немного переделал свою программу в той части чт огенерирует отчет и все заработало. Спасибо за поддержку.

Выгрузка отчета

Добавлено: 05 фев 2007, 12:16
Vital
Ок. Спасибо за сообщение.