-1

I need to convert the following C# code to VB.NET:

if (this.InvokeRequired)
{
    this.BeginInvoke((Action)(() =>
    {
        imageMutex.WaitOne();
        pbCamera.Image = (Bitmap)imageCamera.Clone();
        imageMutex.ReleaseMutex();
    }));
}

I have tried it like this:

If Me.InvokeRequired Then
    Me.BeginInvoke((Action)(Function()
        imageMutex.WaitOne()
        pbCamera.Image = CType(imageCamera.Clone(), Bitmap)
        imageMutex.ReleaseMutex()
   ))
End If

But the compiler tells me that Action is a type and can not be used as an expression. How would such a delegate by written in VB.NET?

Lance U. Matthews
  • 13,224
  • 6
  • 36
  • 62
tmighty
  • 8,222
  • 19
  • 78
  • 182
  • `(Action)` is C#-style casting, which doesn't work in VB.NET. – Lance U. Matthews Apr 21 '20 at 16:23
  • There are free automatic code converters online which can help you. For example, the converter at https://codeconverter.icsharpcode.net/ suggests writing it as `If Me.InvokeRequired Then Me.BeginInvoke(CType((Sub() imageMutex.WaitOne() pbCamera.Image = CType(imageCamera.Clone(), Bitmap) imageMutex.ReleaseMutex() End Sub), Action)) End If ` – ADyson Apr 21 '20 at 16:23
  • 2
    There's no reason to cast the lambda expression to an Action, right? Can't you just write: `Me.BeginInvoke(Sub() ... do code in multiple lines ... End Sub)` ? See [here](https://stackoverflow.com/questions/37278917/how-to-use-begininvoke-in-vb-net)? I'd almost argue this is a duplicate of the question I link to. – Sean Skelly Apr 21 '20 at 16:28
  • Are you sure you want BeginInvoke, and not Invoke? Also, to me it's odd to use InvokeRequired to decide when to execute that processing code, with no Else. – djv Apr 21 '20 at 16:32
  • @djv BeginInvoke is usually safer in WinForms. `pbCamera.Image` looks like a PictureBox control. – LarsTech Apr 21 '20 at 16:36
  • @LarsTech usually safer...? Both run on the correct thread so are equally "safe" however BeginInvoke is asynchronous and should have a matching EndInvoke to ensure threading doesn't get out of hand. – djv Apr 21 '20 at 16:39
  • 1
    @djv See Jon Skeet's answer on [What's the difference between Invoke() and BeginInvoke()](https://stackoverflow.com/a/229558/719186), note the last paragraph. – LarsTech Apr 21 '20 at 16:41
  • @LarsTech I was reading it when you posted this. I would disagree that BeginInvoke is safer if this code may be called in rapid succession without any EndInvoke to control synchronization. In that case it is safer to block with Invoke. My concerns are outside the scope of this code conversion question anyway. The answer is in a couple comments above. – djv Apr 21 '20 at 16:51
  • @djv `BeginInvoke()` doesn't require `EndInvoke()` at all. It *simply* a `Post()` instead of a `Send()`. What you Invoked is posted to the message queue, so executed *asynchronously*. Setting the Image of a PictureBox is not a problem. If you use `Invoke()` and nobody, for any reason, doesn't answer back, then you have a problem you better avoid (by not using `Invoke()`, unless you need a synchronous response and you know that there will be an answer. Setting a property is usually not a problem either, but synchronous). – Jimi Apr 21 '20 at 16:54

1 Answers1

3

The direct translation is:

    If Me.InvokeRequired Then
        Me.BeginInvoke(DirectCast(
            Sub()
                imageMutex.WaitOne()
                pbCamera.Image = DirectCast(imageCamera.Clone(), Bitmap)
                imageMutex.ReleaseMutex()
            End Sub, 
            Action)
        )
    End If

As others have pointed out, you don't need to cast a lambda to an Action:

    If Me.InvokeRequired Then
        Me.BeginInvoke(
            Sub()
                imageMutex.WaitOne()
                pbCamera.Image = DirectCast(imageCamera.Clone(), Bitmap)
                imageMutex.ReleaseMutex()
            End Sub
        )
    End If

https://codeconverter.icsharpcode.net had a good stab at converting this. Might be something to consider if youre doing a lot of work where you're finding the code you want in C# but snagging on a couple of aspects of the conversion

Caius Jard
  • 47,616
  • 4
  • 34
  • 62