Why in the callback method when using AsyncCallback with BeginInvoke do I get the operation “Cross Stream Problem”, invalid exception?

I have a window form that receives data from a scale through a serial port. Since I need an operator to be able to cancel the process, I am doing the process of receiving data in the second thread.

The data collection process receives several readings from the scale one at a time. The form has a label that should be updated with information related to each reading.

I am calling a method to get data from a scale using this code.

Dim ad As New readALine(AddressOf thisScale.readALine)
Dim ac As New AsyncCallback(AddressOf Me.GetDataCallback)
Dim iar As IAsyncResult = ad.BeginInvoke("", ac, ad)

The delegate for the readALine method is defined in the user interface code.

Delegate Function readALine(ByVal toSend As String) As String

GetDataCallback Method:

Private Sub GetDataCallback(ByVal ia As IAsyncResult)
    .
    .
    .
    lblInstructions.Text = _thisMeasure.dt.Rows(_currRow - 1).Item("cnt") & ":"
    lblInstructions.Refresh()
    .
    .
    .
End Sub

I get an exception in the lblInstructions.Text = statement.

, GetDataCallback , , . , , , BackgroundWorker , , .

VS2003 VS2008.

.

, Dave

+3
5

BeginInvoke. Calling Control.BeginInvoke . BeginInvoke - , , . - , , GetDataCallback , .

, GetDataCallback Control.Invoke Control.BeginInvoke .

: Control.InvokeRequired - Invoke/BeginInvoke; , , .

+3

, .

yourForm.BeginInvoke

;

+1

.NET 1.1 , .

.NET 2.0 , , , , , , , UI, , .

Me.InvokeRequired, , . . :

Protected Sub PerformUIOperations()
  If Me.InvokeRequired Then
    'We are currently on a non-UI thread. Invoke this method on the UI thread:
    Me.Invoke(New MethodInvoker(AddressOf Me.PerformUIOperations))
    Return
  End If
  'Perform UI operations when we know it is safe:
  lblInstructions.Text = "blabla"
End Sub

PerformUIOperations , UI, .

, PerformUIOperations (, ), PerformUIOperations MethodInvoker.

0

I have the following in another section of code:

Delegate Sub setValueCallback(ByVal row As Integer, ByVal value As Decimal)
Public Sub setValue(ByVal row As Integer, ByVal value As Decimal)
    If Me.Controls.Item(_tbIndex(row - 1)).InvokeRequired Then
        Dim d As New setValueCallback(AddressOf setValue)
        Me.Invoke(d, New Object() {row, value})
    Else
        Dim tb As TextBox = Me.Controls.Item(_tbIndex(row - 1))
        tb.Text = value
        _dt.Rows(tb.Tag).Item(1) = value
    End If
End Sub

How could this be rewritten so as not to use .InvokeRequired?

0
source

Dave, maybe this is the solution you are looking for:

Dim ad As New readALine(AddressOf thisScale.readALine)
Dim ac As New AsyncCallback(AddressOf Me.GetDataCallback)
Dim iar As IAsyncResult = ad.BeginInvoke("", ac, ad)

Delegate Function readALine(ByVal toSend As String) As String

Private Sub GetDataCallback(ByVal ia As IAsyncResult)
   If lblInstructions.InvokeRequired Then
      lblInstructions.Invoke(New AsyncCallback(AddressOf GetDataCallback), New Object() {ia})
   Else
     .
     .
     lblInstructions.Text = _thisMeasure.dt.Rows(_currRow - 1).Item("cnt") & ":"
     lblInstructions.Refresh()
     .
     .
  End If
End Sub
0
source

Source: https://habr.com/ru/post/1713769/


All Articles