# Using Delegates and BeginInvoke with .NET 2.0 WebServices

I'm attempting to implement a simple long-polling/comet/reverse AJAX solution, and came across the concept of delegates, specifically with the BeginInvoke and EndInvoke methods. I've built a Web Service that uses these concepts, but, having never used these, they make me a little nervous, and I have my doubts as to whether they are actually what I want.

The goal, of course, is to offload the actual processing from IIS processes onto other framework processes, for a reduction in server load when waiting on a long-poll request for data. I can't have gotten this right, but I want to know why and at least get some direction in how it might be better accomplished (not necessarily a solution, but maybe an article or some documentation).

The Web Service code:

Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Threading
Imports System.Runtime.InteropServices

<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class WebService
Inherits System.Web.Services.WebService

<WebMethod()> _
Public Function HelloWorld() As String
Dim threadId As Integer
Dim thing As New Things
Dim caller As New AsyncDoStuff(AddressOf thing.doStuff)
Dim result As IAsyncResult = caller.BeginInvoke(3000, threadId, Nothing, Nothing)

result.AsyncWaitHandle.WaitOne()

Dim returnValue As String = caller.EndInvoke(threadId, result)

result.AsyncWaitHandle.Close()

Return returnValue
End Function
End Class

Public Class Things
Public Function doStuff(ByVal callDuration As Integer, <Out()> ByRef threadId As Integer) As String
' Imagine this method was accessing a database, looking for new information, and returning when it found some
Thread.Sleep(callDuration)
threadId = Thread.CurrentThread.ManagedThreadId()
Return String.Format("My call time was {0}.", callDuration.ToString())
End Function
End Class

Public Delegate Function AsyncDoStuff(ByVal callDuration As Integer, <Out()> ByRef threadID As Integer) As String

• You've never used an event handler? EventHandler is just a delegate with a (Object, EventArgs) signature and no return value. You know delegates more than you think you do. – Mathieu Guindon Nov 22 '13 at 2:48
• Wow. Blast from the past. I never actually got this implemented, opting instead for simple polling with increased intervals when no data was returned. I guess I never trusted myself with off-processes. – Ryan Kinal Nov 22 '13 at 16:36

## 1 Answer

This Stack Overflow answer to the question "Is there a VB.NET equivalent of C# out parameters" is pretty clear:

No, there is no equivalent construct that allows a non-initialised variable to be passed to a method without a warning [...]

However specifying the <Out()> attribute, despite being ignored by VB (ByRef is all you need, really), does allow a C# client to use it as an out parameter - so good call then!

Declaring the delegate at the bottom of the module, after it's being used, makes it uselessly confusing and prompts for unnecessary scrolling; I would have put it at the top... actually, I would have made the delegate a public member of the WebService class:

Public Class WebService
Inherits System.Web.Services.WebService

Public Delegate Function AsyncDoStuff(ByVal callDuration As Integer, <Out()> ByRef threadID As Integer) As String

'...


I very, very seldom declare my own delegate types, if at all. I don't like ref ByRef and out <Out()> parameters either - I think they should be avoided.

In this case I would have gone with a Func<int,AsyncStuffResult> (please excuse the C# notation), where the int parameter is the callDuration, and the AsyncStuffResult is a class that encapsulates everything you want to return from the function call - whatever that is.

This way if/when you need to return more things, your signature doesn't need to change, you only add new members to your result class - note that the EventArgs class fulfills the same goal.

Public Class AsyncStuffResult
'- expose ThreadId as a get-only property
'- expose your String result as a get-only property, too
'- expose a constructor to assign the members
End Class

• Death to delegates!!! – IEatBagels Sep 26 '14 at 18:46