2016-12-17 9 views
2

スレッドで同時に多くのジョブを実行するサーバープログラムを作成しました。スレッド:スレッドをブロックせずにUIを更新しますか?

これらのスレッドでは、ステータス情報でListViewを更新する必要がありますが、現在は呼び出しを使用しているため、スレッドはUIがListViewの更新を完了するのを待ちます。

ListViewにステータスを送信し、ListViewの更新が完了している間にスレッドを続行する方法については、十分にアドバイスしてください。

ここに私のコードだ

...

Public Delegate Sub InfoDelegate(status As String) 

Public Sub Info(status As String) 
    If Me.InvokeRequired Then 
     Dim d As New InfoDelegate(AddressOf Info) 
     Me.Invoke(d, status) 
    Else 
     Dim item As New ListViewItem With { 
      .Text = status} 

     With lv 
      .BeginUpdate() 
      .Items.Insert(0, item) 
      If .Items.Count > 500 Then 
       For i As Integer = Me.lv.Items.Count - 1 To 500 Step -1 
        Me.lv.Items.RemoveAt(i) 
       Next 
      End If 
      .EndUpdate() 
     End With 
    End If 
End Sub 
+0

利用代わりBeginInvoke':

は、ここでの例です。 – jmcilhinney

+0

「EndInvoke」も呼び出す必要があることを覚えておいてください! –

+0

@VisualVincentあなたは本当ですか?マイクロソフトではEndInvokeを呼び出しません... https://msdn.microsoft.com/en-us/library/a06c0dc2(v=vs.110).aspx – MojoDK

答えて

2

あなたは非同期メソッドを呼び出すためにControl.BeginInvoke()を呼び出すことができます。ただし、その呼び出しの後にEndInvoke()コールを続ける必要があります。そうしないと、メモリやスレッドリークが発生します。

.NET Framework 4.0以降では、lambda expressionsを使用して、BeginInvoke呼び出しから返されたIAsyncResultをラムダ式自体に渡すことができます。したがって、非同期操作が既に終了しているので、ブロックすることなくEndInvokeを呼び出すことができます。 `

Dim iar As IAsyncResult = _ 
    Me.BeginInvoke(Sub() 
            Info("Status here") 'Calling your Info() method. 
            Me.EndInvoke(iar) 
           End Sub) 
+0

あなたは最高です!ありがとう!これは本当に私に多くの助けになります。 – MojoDK

+0

@MojoDK:問題ありません。うれしいです! –

+1

私は、あなたが 'EndInvoke'を呼び出さなければならないと間違っていると思います。これはMSDNからのものです: "必要であれば、デリゲートから戻り値を取得するためにEndInvokeを呼び出すことができますが、これは必須ではありません。戻り値が取得できるまでEndInvokeはブロックされます"。したがって、あなたは呼び出された関数から戻り値を得るために 'EndInvoke'を呼び出すことができますが、そうでなければあなたは持っていません。 – jmcilhinney

関連する問題