2013-03-15 3 views
3

У меня возникли некоторые проблемы с ReportViewer. В основном код выглядит следующим образом:WinForms ReportViewer зависает приложение WPF

public void Display(object dataSource, ReportViewer viewer) 
    { 
     currentDs = dataSource as MyTypes; 

     if (currentDs != null) 
     { 
      var param = new LinkedList<ReportParameter>(); 
      param.AddFirst(new ReportParameter("Title", "Title")); 
      viewer.ProcessingMode = ProcessingMode.Local; 
      viewer.LocalReport.ReportEmbeddedResource = ReportName; 
      viewer.LocalReport.EnableExternalImages = true; 
      viewer.LocalReport.DataSources.Add(new ReportDataSource(DataSourceName + "_Header", currentDs.Header)); 
      viewer.LocalReport.DataSources.Add(new ReportDataSource(DataSourceName + "_Footer", currentDs.Footer)); 
      viewer.LocalReport.DataSources.Add(new ReportDataSource(DataSourceName + "_Lines", currentDs.Lines)); 

      viewer.LocalReport.SetParameters(param); 
      viewer.RefreshReport(); 
     } 
    } 

Проблема заключается в том, что иногда он генерирует отчет RDLC, но другие просто виснет приложение. В частности, он остается в viewer.RefreshReport(); навсегда.

Соответствующие параметры и наборы данных правильно установлены в файле rdlc.

Неужели кто-нибудь испытал подобное поведение?

Заранее спасибо.

+0

происходит случайным образом при использовании тех же параметров? – WiiMaxx

+0

есть. Иногда висят, а другие - не одни и те же. –

+0

У меня в вашем наборе данных есть все те же значения? – WiiMaxx

ответ

1

Возможно, я исправил его.Эта страница помогла мне разобраться: http://ikriv.com/dev/dotnet/MysteriousHang.html

Итак, кажется, что в потоке пользовательского интерфейса необходимо создать a) средство просмотра отчетов, которое не всегда надежно (см. Ссылку для подробностей). Просмотр отчетов является компонентом .NET 2, а поведение документировано в ссылке относится к .NET 2.

Чтобы исправить это, я использовал следующие приемы:

  • первого трюк: название потока пользовательского интерфейса при запуске
  • второй трюк: сначала надавите на ручку, затем получите ссылку на контекст синхронизации.
  • Третий трюк: используйте имя потока и контекст синхронизации для выполнения требуемого вызова -> invoke idiom.

Если все это удерживается вместе, я вернусь и напишу w/more details.

3

Предполагаю, что у вас есть ваш зритель configured правильно.

Действительно ли первое поколение обычно преуспевает? Вы можете попробовать позвонить viewer.Reset() после каждого поколения отчетов, что может решить некоторые проблемы с рецептурой.

3

Существует a post from 2006, что на первый взгляд кажется актуальным и может дать вам обходной путь, хотя я должен признать, что я не сделал этого сам, потому что мне было бы почти невозможно воссоздать проблему, которую вы видите и поэтому было бы невозможно понять, устранит ли это обходное решение. Это не идеальный вариант, но я надеюсь, что нет такой вещи, как бесполезная информация :-)

Соответствующая информация находится в нижней части связанной темы и для большей ясности я процитировал ее ниже.

Управление ReportViewer разбито на два компонента - объекты отчета (отображаются как .ServerReport и .LocalReport) и пользовательский интерфейс (фактический класс ReportViewer). Объекты отчета хранят все данные о вашем отчете. Компонент пользовательского интерфейса просто вызывает в них информацию, необходимую для отображения отчета, подсказок параметров, панели инструментов и т. Д.

Компонент пользовательского интерфейса не является потокобезопасным, как и большинство элементов управления. Но объекты отчета являются потокобезопасными. Когда вы вызываете RefreshReport, зритель использует фоновый поток для вызова Render в объекте отчета. Но это не единственный раз, когда элемент управления вызывает объект отчета. Первый раз, когда он должен скомпилировать определение отчета (локальный отчет) или создать сеанс (отчет сервера), может занять много времени. Если это «первый раз» во время RefreshReport, это произойдет в фоновом потоке. Но, как вы видели, это может произойти в другое время. Например, для заполнения параметров UI требуется вызвать GetParameters, что также требует этого штрафа за запуск.

Если вы хотите гарантировать, что это «первое время» накладывается на фоновый поток, то после установки пути отчета и другой информации о соединении/источнике данных вызовите GetParameters из фонового потока.

Это наводит на мысль, что вы делаете несколько звонков на ваш ReportViewer всегда из фонового потока, а не из потока пользовательского интерфейса, так что любые задержки не влияют на пользовательский интерфейс. Похоже, это звучит для меня немного уместным дизайном!

Вы можете мне помочь?

0

я столкнулся вопрос в Windows XP с .Net 4.0 и просмотра отчетов 2010. Да ОС конец поддержки, но Windows Embedded POSReady 2009 (Windows XP SP3), она все еще в расширенной поддержкой до апреля 2019 года

чтобы обойти вишу, вызовите устаревший API для подготовить отчет

rptviewer.LocalReport.ExecuteReportInSandboxAppDomain(); 

и при выходе или повторно запустить отчет, например, Параметры отчета изменился, отчет необходимо очистить должным

rptviewer.LocalReport.DataSources.Clear(); 
rptviewer.LocalReport.ReportEmbeddedResource = null; 
rptviewer.LocalReport.Dispose(); 
// release sandbox is required to prevent the lock up, see below note on display report 
rptviewer.LocalReport.ReleaseSandboxAppDomain(); 

// clean up report viewer 
rptviewer.Clear(); 
rptviewer.Reset(); 

Обратите внимание на Windows 7, 8, 8.1 и 10. Проблема зависания не произошло.

Смежные вопросы