lkosson / reportviewercore

Recompilation of Microsoft.ReportViewer for .NET Core 3.1+
414 stars 121 forks source link

Thread.Abort call by ReportViewer #31

Closed AlanMichaelDobson closed 3 years ago

AlanMichaelDobson commented 3 years ago

Hi

This is my first ever post to this type of environment so please be kind. We have converted to .Net 5 and have a windows based code part which does our reporting. Whilst rendering a report we get this exception if the user quits out of the window before the report is ready. Thread.Abort is raising PlatformNotSupportedException. I am currently upgrading to use the CancelRendering method.

Is that the correct approach? Is the Thread.Abort being removed? Is what I have posted on this issue correct?

Thanks in advance Alan Dobson

We are using namespace

Microsoft.Reporting.WinForms { [Designer("Microsoft.Reporting.WinForms.ReportViewerDesigner, Microsoft.ReportViewer.Design, Version=15.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91", typeof(IDesigner))] [Docking(DockingBehavior.Ask)] [SRDescriptionAttribute("ReportViewerDescription")] public class ReportViewer : UserControl, IRenderable

ExceptionType: System.PlatformNotSupportedException TargetSite: Void Abort() Message: Thread abort is not supported on this platform. Data: HelpLink: NULL Source: System.Private.CoreLib HResult: -2146233031 StackTrace: at System.Threading.Thread.Abort() at Microsoft.Reporting.WinForms.ProcessingThread.Cancel(Int32 millisecondsTimeout) at Microsoft.Reporting.WinForms.ReportViewer.CancelRendering(Int32 millisecondsTimeout) at Microsoft.Reporting.WinForms.ReportViewer.CancelAllRenderingRequests() at Microsoft.Reporting.WinForms.ReportViewer.Dispose(Boolean disposing) at System.Windows.Forms.Control.Dispose(Boolean disposing) at System.Windows.Forms.Form.Dispose(Boolean disposing) at SDS.Windows.Forms.BaseForm.Dispose(Boolean disposing) at SDS.Optical.Windows.Reports.Forms.ReportPreviewRPLFormCode.Dispose(Boolean disposing) at System.Windows.Forms.Form.WmClose(Message& m) at System.Windows.Forms.Form.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, WM msg, IntPtr wparam, IntPtr lparam)

lkosson commented 3 years ago

Hello,

you are right - Thread.Abort is indeed removed in .NET Core. It is invoked indirectly by both CancelRendering and Dispose on Microsoft.Reporting.WinForms.ReportViewer control. It looks as if original ReportViewer has no support for cooperative cancellation. Perhaps there is one in server-side version of Reporting Services. I'll see if I can graft one to this project.

For now, as a workaround, I have changed behaviour of CancelRendering to abandon worker thread instead of crashing whole application. The change will be included in upcoming NuGet package.

AlanMichaelDobson commented 3 years ago

Thank you very much. Appreciate the response

AlanMichaelDobson commented 3 years ago

Hi

Did you manage to add cooperative cancellation ?

Thanks

lkosson commented 3 years ago

Reporting Services don't support graceful cancellation either. It uses Thread.Abort like ReportViewer. There is not much hope to implement actual cooperative cancellation. One can either wait for worker thread to finish its job, or abandon it and let it continue in background.

On Windows hosts it could be possible to invoke TerminateThread via WinAPI, but most likely that would leave the whole process unstable.

AlanMichaelDobson commented 3 years ago

I bow to your knowledge. Happy with solution you have provided