JLovero

Hello.

I am having a bit of a problem using Delegate.BeginInvoke. Actually, the asynchronous method calls are working just fine and the callback methods are called correctly. I have a long-running method that returns a typed dataset. That dataset is then used to populate an Active Report document in a new WinForms window. However, the attempt to create the Report Viewer WinForm throws an exception in the constructor. Here are the relevant bits of code:

Private Sub btnRunReport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRunReport.Click

'Code to get values from the UI, etc.
Dim dr As New DataRules

Dim crDelegate As New CarrierReportDelegate(AddressOf dr.ReturnDataForCarrierReport)

crDelegate.BeginInvoke(New AsyncCallback(AddressOf CarrierReportCallback), Nothing)

End Sub

Private Sub CarrierReportCallback(ByVal result As IAsyncResult)

Dim crDelegate As CarrierReportDelegate = CType(CType(result, AsyncResult).AsyncDelegate, CarrierReportDelegate)

'Typed dataset returned by async method invocation assigned to member variable
_cfdData = crDelegate.EndInvoke(result)

Dim viewer As New ReportViewer(_cfdData) 'This is where the error is thrown
viewer.ShowDialog(Me)

End Sub

Somewhere within the InitializeComponent method called from the ReportViewer constructor is where the following exception is thrown: DragDrop registration failed. This has something to do with the ActiveReport viewer control, but it worked as expected before I restructured the code to use the asynchronous delegate invocation. As such, I think the problem is not the viewer control, but a threading issue of some sort. It was my understanding that the callback method ran on the original thread, not the thread created by the async call. Is that wrong Can anyone give some insight into what is happening here Is there a way to make sure that the ReportViewer gets created by the original thread

Thanks,
JML


Re: Visual Basic Language Exception when creating a new WinForm in an Async Delegate Callback method

Timothy Ng MSFT

You are correct, it's most likely a threading issue. The thread that executes the delegate when you ask for asynchronous invocation is a thread pool thread (ie, not the original, main UI thread). You can verify this by putting a breakpoint in your delegate handler, and looking at the "threads" window in the debugger.

You can try the following links for examples on how to marshal your call back:

http://msdn.microsoft.com/library/default.asp url=/library/en-us/cpguide/html/cpcondevelopingmultithreadedwindowsformscontrol.asp
http://msdn.microsoft.com/msdnmag/issues/03/02/Multithreading/




Re: Visual Basic Language Exception when creating a new WinForm in an Async Delegate Callback method

Dick Donny

Hi

You are using an STA thread model and trying to create a form on a thread that is not the one used by the application's message dispatcher.

As your code appears to be within a form already, the simplest way to marshall the call correctly is to let the form do it .. something along these lines ....

_cfddata = crdelegate.endinvoke(result)

showreport

Now add your new procedure

sub showreport

if mybase.invokerequired then

mybase.invoke(new methodinvoker(addressof me.showreport))

else : new reportviewer(_cfddata).showdialog(me)

end if

end sub

Hopefully this should solve your problem ... let me know if it does not, or if any of the above is unclear.

Richard