Deadlock in ReportViewer?

Hi there, I'm stumped by the following: My program loads a report into a ReportViewer control (in LOCAL mode!), populates its datasets, then executes the report. Then I start changing the paper source and orientation in the Page Setup button in the toolbar. Every 20 times or so that I change something and click OK, the entire app hangs, showing the animated green circle (now frozen) and "Report is being generated". I can attach a Visual Studio debugger, and I get the following stack traces for two of the 5 or 6 running threads. Anybody seen this before, or have an idea of what's going on

FIRST THREAD
 	[In a sleep, wait, or join]	
> mscorlib.dll!System.Threading.WaitHandle.WaitOne(long timeout, bool exitContext) + 0x2e bytes
mscorlib.dll!System.Threading.WaitHandle.WaitOne(int millisecondsTimeout, bool exitContext) + 0x23 bytes
mscorlib.dll!System.Threading.WaitHandle.WaitOne() + 0xa bytes
Microsoft.ReportViewer.WinForms.dll!Microsoft.Reporting.WinForms.FileManager.WaitForNextPage() + 0x61 bytes
Microsoft.ReportViewer.WinForms.dll!Microsoft.Reporting.WinForms.FileManager.Get(int page = 8) + 0x86 bytes
Microsoft.ReportViewer.WinForms.dll!Microsoft.Reporting.WinForms.ReportViewer.SetViewForCurrentPage(Microsoft.Reporting.WinForms.UIState state = ProcessingPartial, bool isDifferentReport, Microsoft.Reporting.WinForms.ActionType actionType = None, string actionID = null) + 0x60 bytes
Microsoft.ReportViewer.WinForms.dll!Microsoft.Reporting.WinForms.ReportViewer.OnPrintPreviewPageAvailableUI(int pageNumber, bool isLastPage) + 0x3a bytes
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.Delegate.DynamicInvokeImpl(object[] args) + 0x5a bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackDo(System.Windows.Forms.Control.ThreadMethodEntry tme) + 0x9d bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(object obj) + 0x6b bytes
mscorlib.dll!System.Threading.ExecutionContext.runTryCode(object userData) + 0x43 bytes
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0xa7 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x92 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallback(System.Windows.Forms.Control.ThreadMethodEntry tme) + 0x90 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbacks() + 0xc0 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x800 bytes
System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl.WndProc(ref System.Windows.Forms.Message m) + 0x45 bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.WndProc(ref System.Windows.Forms.Message m) + 0x13 bytes
System.Windows.Forms.dll!System.Windows.Forms.UserControl.WndProc(ref System.Windows.Forms.Message m) + 0x11 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0xd bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0xd6 bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg = 49844, System.IntPtr wparam, System.IntPtr lparam) + 0x75 bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason = -1, int pvLoopData = 0) + 0x2ea bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x17d bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x53 bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm) + 0x2e bytes
SurveyorReporter.exe!My.Reporting.App.Program.Main() + 0x69 bytes


SECOND THREAD
> System.Drawing.dll!System.Drawing.ImageAnimator.AnimateImages50ms() + 0x141 bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x3b bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x81 bytes

mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x40 bytes



Answer this question

Deadlock in ReportViewer?

  • bryanedds

    Some more information - here's the two stack traces. I believe this had something to do specifically to do with an MDI host form, a child form, and a 3rd dialog form which had menus attached to them (only because the other thread that appears to be part of the deadlock is in a call to UpdateMenuHandles):

    Image Animator thread:

    > system.drawing.dll!System.Drawing.ImageAnimator.ThreadProcImpl() + 0x63 bytes

    Other thread:

    system.windows.forms.dll!System.Windows.Forms.Form.UpdateMenuHandles(System.Windows.Forms.MainMenu menu = <undefined value>, bool forceRedraw = true) + 0x164 bytes
    system.windows.forms.dll!System.Windows.Forms.Form.UpdateMenuHandles() + 0xc5 bytes
    system.windows.forms.dll!System.Windows.Forms.Form.MenuChanged(int change = 0, System.Windows.Forms.Menu menu = <undefined value>) + 0xc4 bytes
    system.windows.forms.dll!System.Windows.Forms.Form.Dispose(bool disposing = true) + 0x332 bytes
    > WindowHandleWindows.exe!WindowHandleWindows.DialogForm.Dispose(bool disposing = true) Line 48 C#
    system.dll!System.ComponentModel.Component.Dispose() + 0x13 bytes
    WindowHandleWindows.exe!WindowHandleWindows.ChildForm.button1_Click(System.Object sender = {System.Windows.Forms.Button}, System.EventArgs e = {System.EventArgs}) Line 136 + 0x32 bytes C#
    system.windows.forms.dll!System.Windows.Forms.Control.OnClick(System.EventArgs e = {System.EventArgs}) + 0x62 bytes
    system.windows.forms.dll!System.Windows.Forms.Button.OnClick(System.EventArgs e = {System.EventArgs}) + 0x56 bytes
    system.windows.forms.dll!System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs mevent = {X=37 Y=14 Button=Left}) + 0x119 bytes
    system.windows.forms.dll!System.Windows.Forms.Control.WmMouseUp(System.Windows.Forms.Message m = {System.Windows.Forms.Message}, System.Windows.Forms.MouseButtons button = Left, int clicks = 1) + 0x235 bytes
    system.windows.forms.dll!System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0x4a1 bytes
    system.windows.forms.dll!System.Windows.Forms.ButtonBase.WndProc(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0x11c bytes
    system.windows.forms.dll!System.Windows.Forms.Button.WndProc(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0x8d bytes
    system.windows.forms.dll!ControlNativeWindow.OnMessage(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0x19 bytes
    system.windows.forms.dll!ControlNativeWindow.WndProc(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0xda bytes
    system.windows.forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(int hWnd = 7931074, int msg = 514, int wparam = 0, int lparam = 917541) + 0x39 bytes
    system.windows.forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(int dwComponentID = 1, int reason = -1, int pvLoopData = 0) + 0x2fa bytes
    system.windows.forms.dll!ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x1db bytes
    system.windows.forms.dll!ThreadContext.RunMessageLoop(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x4f bytes
    system.windows.forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm = {WindowHandleWindows.Form1}) + 0x37 bytes
    WindowHandleWindows.exe!WindowHandleWindows.Form1.Main() Line 107 C#


  • Belias

    I just verified that this is fixed in Orcas Beta 1. Thanks Brian et al. Now to get the bug fix latency down to < 1 year...

  • Jough

    Thank you very much for looking into this!

  • Binu Jeesman

    With a little more time, I've come up with a 100% consistent repro for this. Would someone at Microsoft be interested in a bug report I'm too lazy to figure out a way to post my entire Visual Studio solution, but it's very basic. I'm on a WinXP Pro SP2 box.
    1. Use Visual Studio to "design" a report that has no datasets, is totally blank, but the report size is set to be very tall (e.g. 6.5 x 82 inches). I called mine LongReport.rdl
    2. Create a Windows application, add the appropriate ReportViewer dll references. In the designer for Form1, add a ReportViewer control. Edit the Form1.Load event to call the following function:
      <code>
      private void Form1_Load(object sender, EventArgs e)
      {
      this.reportViewer1.LocalReport.LoadReportDefinition(
      new StreamReader(@"LongReport.rdl"));
      this.reportViewer1.RefreshReport();
      }
      </code>

      Oh yeah, this means LongReport.rdl needs to be in the bin\Debug directory. I added LongReport.rdl to the project and set Copy to Output Directory = Copy if newer.
    3. Build & run the app, and do the following:
      1. Click on the Print Layout button to toggle into print layout view.
      2. Click the Page Setup button. Select Landscape, click OK.
      3. Click the Last Page button to go to the last page of the report (for me, it's page 13... page size is U.S. Letter by default)
      4. Click Page Setup again, select Portrait, click OK

    At this point the application hangs, as I described.


  • RTIS1

    Thank you for reporting this issue.

    This looks like a bug, though I'm seeing different behavior. Instead of the application hang, I'm seeing a null reference exception, but given the call stack you see, I think this is just the result of the threads running such that I get by the deadlock. It's the result of the viewer trying to display a page of the report that no longer exists after the page size change. Navigating to page 1 first (or any other page that still exists) will work around the issue.


  • Shrini

    Interesting that you just posted this, as I'm having a similar issue but with a simple animated GIF file on a form that does nothing but wait for a background thread to complete and then close. It certainly looks like a deadlock with the ImageAnimator class in .Net 1.1 when the form is disposed while the animator is running. Even when using form.Invoke to get back to the UI thread when closing the form, I will get a deadlock every now and then. I've got a simple repro case using nothing but base .Net framework code. I haven't tested it on .Net framework 2.0 yet... have to look into that. However, it also seems that this behavior is more likely to be exhibited in a Citrix environment than running on a normal desktop machine.

    Is there somewhere I can send the repro case Although I've found a work-around that has made the issue less common, it is still occurring.

    Doug Rohrer


  • Deadlock in ReportViewer?