2017-05-30 4 views
0

スレッド内でループを作成しようとしましたが、テキストボックスに値が表示されている間もフォームで作業を続けます。 問題は、起動時にボタンを押したりコマンドを設定したりするなど、何もできないということです。ここでvb.netどうすれば各ループにどのスレッドが計算中であり、フォーム内で作業を続けることができますか?

はコードの考えです:

Imports System.Threading 

Public Class Form1 

    Dim trd As System.Threading.Thread 
    Dim cont As Integer 

    Private Sub btnOpen_Click(sender As Object, e As EventArgs) Handles btnOpen.Click 
      cont = 0 
      trd = New Thread(AddressOf trdReadAxis) 
      trd.Start() 
    End Sub 

    Private Delegate Sub CloseFormCallback() 
    Private Sub trdReadAxis() 
     While cont < 10 
      If InvokeRequired Then 
       Dim d As New CloseFormCallback(AddressOf trdReadAxis) 
       Invoke(d, Nothing) 
      Else 
       txtXPosition.Text = cont 
       cont += 1 
       Thread.Sleep(1000) 
      End If 
     end while 
    end class 

私は私のテキストボックスにeveri第2の変更「txtXPosition」を参照して何ができますか?

ありがとうございます。

+0

使用 'txtXPosition.Update()'や 'txtXPosition.Refresh()' ...理由フォームとコントロールがロックされるのは、UIスレッドでコードを実行しているためです。 – Codexer

+0

実装が簡単で、事前に定義されているため、[BackgroundWorker](https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v = vs.110).aspx)の使用をお勧めしますそのような仕事 –

答えて

1

このコードは混乱です:

Private Sub trdReadAxis() 
    While cont < 10 
     If InvokeRequired Then 
      Dim d As New CloseFormCallback(AddressOf trdReadAxis) 
      Invoke(d, Nothing) 
     Else 
      txtXPosition.Text = cont 
      cont += 1 
      Thread.Sleep(1000) 
      End If 
    End while 
End Sub 

あなたのワーカースレッドは、それがUIスレッド上で実行されますInvoke、経由で自身をコールバックするように見えます。ループが終了すると、それはループのすべての反復でSleep(1000)というUIスレッド上のwhileループ全体を通過します。これはあなたのクリックとキーストロークを処理するはずのメッセージループをロックアウトします。

私はそうのように、あなたはテキストボックスを更新するコードからワーカースレッドを分ける提案:

Delegate SetTextCallBack(ByVal message as string) 

Private Sub SetText(ByVal message as String) 
    if InvokedRequired then 
     Dim d As New SetTextCallback(AddressOf SetText) 
     Invoke(d, message) 
    Else 
     txtXPosition.Text = message 
    End If 
end sub 

Private Sub trdReadAxis() 
    While cont < 10 
     SetText cont 
     cont += 1 
     Thread.Sleep(1000) 
    End while 
End Sub 
+0

ニースの答え!私は 'Dim a as Array(1)'はむしろ余計なコードであることを指摘したいと思います。 [** 'Control.Invoke()' **](https://msdn.microsoft.com/en-us/library/a1hetckb(v = vs.110).aspx)は 'ParamArray'を期待していますので、変数を直接呼び出します: 'Invoke(d、message)' - ほとんどの場合、 'Invoke(d、New Object(){message})'を実行できます。 –

+0

ありがとう、編集されました。通常VBの人ではない:/ –

関連する問題