3

Consider the following C# code:

private void SomeMethod()
{
    IsBusy = true;
    var bg = new BackgroundWorker();
    bg.DoWork += (sender, e) =>
    {
      //do some work
    };
    bg.RunWorkerCompleted += (sender, e) =>
    {
      IsBusy = false;
    };
    bg.RunWorkerAsync();
}

I know VB.NET won't allow directly referencing DoWork like that and you have to setup the worker by saying Private WithEvents Worker As BackgroundWorker and explicitly handling the DoWork event as follows:

Private Sub Worker_DoWork( 
            ByVal sender As Object,
            ByVal e As DoWorkEventArgs) _
            Handles Worker.DoWork

    ...

End Sub

However, I'd like to be able to implement a method like SomeMethod from the C# example in VB.net. Likely this means wrapping the Backgroundworker in another class (which is something I want to do for dependency injection and unit testing anyway). I'm just not sure how to go about it in a simple, elegant way.

1
  • I don't use VB, but thanks & +1 for an example of concisely encapsulating a bg worker, call back and all, within a method. Commented Jun 20, 2018 at 12:19

2 Answers 2

5

You can directly reference DoWork just like in C# by using the AddHandler keyword:

AddHandler bg.DoWork, Sub(sender, e)
                          DoSomething()
                      End Sub
AddHandler bg.RunWorkerCompleted, Sub(sender, e)
                                      IsBusy = False
                                  End Sub
bg.RunWorkerAsync()

Note that this only works on VB10, as earlier versions of VB don't support multi-statement lambdas.

Sign up to request clarification or add additional context in comments.

8 Comments

@Sven, the hint about .NET 4 is not quite accurate. It's not .NET 4 that's required, but a recent version of the VB.NET compiler -- version 10, which ships with .NET 4 / Visual Studio 2010. But the code emitted by that compiler should run even in a .NET 2.0 application.
Yes, I know, that's why I edited my answer to change that. :) Also, I was first and you got accepted? Life isn't fair. :P
@Sven, I didn't realize you were first (both said answered x mins ago). I did give you +1 though.
We were 40 seconds apart or so. It doesn't matter anyway, the important thing is your question got answered. :)
+1 @Sven for correcting your answer. And I see that the other issue has been taken care of. :-) (@Matt, I don't mind at all.)
|
5

If you're using VB.NET 10 (which comes with Visual Studio 2010), the following should work fine:

Dim bg = New BackgroundWorker()
AddHandler bg.DoWork,
    Sub()
        DoSomething()
    End Sub
AddHandler bg.RunWorkerCompleted,
    Sub()
        IsBusy = False
    End Sub
bg.RunWorkerAsync()

VB.NET 10 is required here because earlier versions of VB.NET did not permit lambdas (anonymous Subs that is) that span more than one line.

That being said, you should be able to target earlier versions of the .NET Framework, because the above code is compatible with version 2 of the CLR.

4 Comments

Thanks! All the examples I've seen for VB regarding the Background worker did not use the handlers like this and used the method approach instead. Thanks for clearing this up, and yes I'm using VS2010 (just started recently).
@Matt, in that case, it's probably worth noting that you're allowed to omit parameters with inline Subs: The event handlers shown in my answer omit the usual event handler parameters sender and e, but you could write Sub(sender, e) ... if you needed access to these arguments.
@stalx, Thanks, I didn't know you could omit them either. However I noticed that when saying: AddHandler bg.ProgressChanged, Sub(sender, e) if I hover over e VS says e As System.ComponentModel.ProgressChangedEventArgs, but when I use e in the lambda it is only of type object. I have to explicitly declare the parameter (or cast it) to get it to act as the correct type. Why doesn't vb know what it is outside the lambda signature when it isn't explicitly declared?
@Matt, good question. Now that you say it, I remember having had the same issue. It seems possible that Visual Studio's IntelliSense is quite separate from the compiler and has its own type deduction logic, which might be somewhat smarter in some cases than the compiler's...?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.