views:

112

answers:

2

I'm stuck on converting this C# code to VB:

AsyncHelpers.Async.Do(delegate { WriteStuff("additional stuff..."); });

I was thinking it would be something like

AsyncHelpers.Async.Do(Function() WriteStuff("additional stuff...")

but I get the error "Expression does not produce a value".

Can someone please give me the appropriate VB.Net translation?

Thanks.

========== UPDATE

.
. 
. 

             Async.Do(New DlgR(AddressOf WriteStuff))


        End Sub

        Friend Shared Sub WriteStuff(ByVal thisStr As String)
            'do stuff with thisStr

        End Sub

Based on Brian's suggestion below, this still doesn't work.

How do I get the parameter passed to WriteStuff?

Lastly, I'm also getting signature compatibility error with delegate function DlgR() as object.

+1  A: 

VB.Net doesn't do a very good job supporting lambda expressions (see Use Lambda Expression within ASP.NET MVC View using VB.NET).

You can try something like this...

Sub Main()
    Async.Do(New DlgR(AddressOf WriteStuff))
End Sub
Public Function WriteStuff(ByVal msg As String) As Object
    Console.WriteLine(msg)
    Return Nothing
End Function

Based on your code, I assume you were following the CodeProject article, Towards Cleaner Code, A C# Asynchronous Helper so I used the name and signature of the delegate from that in my example. If you are using another library, the name and signature of the delegate might be different.

UPDATE: VB.Net does not support closures (check out http://msmvps.com/blogs/bill/archive/2006/04/05/89370.aspx for more info) so you cannot, as far as I can tell, pass parameters to the method. The simplest way I can think of to do this is to create your own closure class and call it like this...

Module Module1
    Sub Main()
        Dim c1 = New MyClosure("Hello World")
        Dim c2 = New MyClosure("Test 123")
        CodeToast.Async.Do(New Dlg(AddressOf c1.WriteStuff))
        CodeToast.Async.Do(New Dlg(AddressOf c2.WriteStuff))
        Console.ReadKey()
    End Sub
End Module
Public Class MyClosure
    Public Sub New(ByVal msg As String)
        Message = msg
    End Sub
    Public Message As String
    Public Sub WriteStuff()
        Console.WriteLine(Message)
    End Sub
End Class
Brian
For info, VB 10 in VS2010 will support subroutine lambdas, including multiline lambdas. This should be out pretty soon, so this may also be an option depending on Eli's timeframes, deployment requirements, availability of VS2010 to his team, etc. etc.
itowlson
Good point. I was going to mention that but forgot after trying to figure out what AsyncHelpers was so I could figure out what the signature was :). Thanks for adding it.
Brian
Brian,Yes, this the class I'm trying to use, so implement async method calls.As per my edit above, using your example, how would you then pass parameters to WriteStuff?As C# is more my ground, and this is new VB ground for me, so could you please provide me with a fully-working source? Thanks.
ElHaix
... also, I'm trying to use this with the MS Enterprise Library Logger.Write. Since this class is not static, will this even work?
ElHaix
Brian, I had the same worries at first, about passing parameters to the method. However, check out my solution below - and its working.
ElHaix
A: 

Finally got around to solving this, in the 'more than one line' it is in C#...

I declared my delegate at the class level:

Public Delegate Sub loggerDelegate(ByVal a As LogEntry)

Then, inside my method, I make the async logging call

    ' make the async logging call
    Dim myDel As loggerDelegate = New loggerDelegate(AddressOf Logger.Write)
    myDel(logEntry)

I guess I should have called this, Asynchronous Logging with MS Enterprise Library without using MSMQ, but you get the drift.

Hope this helps someone else.

ElHaix