2016-12-17 1 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 확실합니까? Microsoft는 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를 호출 할 수 있지만 필수는 아닙니다 .EntInvoke는 반환 값을 검색 할 수있을 때까지 차단됩니다". 따라서 호출 된 함수에서 반환 값을 가져 오기 위해'EndInvoke'를 호출 할 수 있지만 그렇지 않은 경우는 없습니다. – jmcilhinney

관련 문제