2013-09-24 4 views
0

Я новичок в multithreading.I гугле некоторые основные примеры ниже приведен кодПочему эта простая многопоточность не working.UI зависанию

Imports System.Threading 
Public Class Form1 
Dim t As New Thread(AddressOf Me.BackgroundProcess) 
Private Sub btnStartThread_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStartThread.Click 
    t.Start() 
End Sub 

Private Sub StopButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StopButton.Click 
    t.Abort() 
End Sub 

Public Sub BackgroundProcess() 
    Dim i As Integer = 1 

    If Me.InvokeRequired Then 
     Me.Invoke(New MethodInvoker(AddressOf BackgroundProcess)) 
    Else 
     Do While True 
      Me.ListBox1.Items.Add("Iteration:" & i) 
      i += 1 
     Loop 
    End If 
End Sub 
End Class 

Когда я нажимаю на резьб мой интерфейс становится unresponsive.What будет причина this.Below скриншот пользовательского интерфейса Form1

+0

Что такое точка этого кода? Это не очень полезно для Threading. Весь ваш код выполняется в пользовательском интерфейсе. – dbasnett

+0

@dbasnett Я изучаю многопоточность. Это просто базовое использование. Если у вас есть какие-либо другие ссылки, пожалуйста, поделитесь. Спасибо – Sachin

ответ

1

Ваш код в «Фон» нить проверяет, если в потоке пользовательского интерфейса

If Me.InvokeRequired Then 

, а если нет, он сообщает, что он работает в потоке пользовательского интерфейса.

Me.Invoke(New MethodInvoker(AddressOf BackgroundProcess)) 

Если в потоке пользовательского интерфейса, он сидит в петле, блокируя поток пользовательского интерфейса, без прокачки.

Do While True 

Чтобы получить эту работу, один из многих способов сделать это так:

Public Delegate Sub AddItemDelegate(ByVal item As Object) 
Public Sub BackgroundProcess() 
    Dim i As Integer = 1 

    Do While True 
     i += 1 
     If Me.InvokeRequired Then 
      Me.Invoke(New AddItemDelegate(AddressOf AddItem), "Iteration:" & i) 
     Else 
      AddItem("Iteration:" & i) 
     End If 
    Loop 
End Sub 
Private Sub AddItem(ByVal item As Object) 
    Me.ListBox1.Items.Add(item) 
End Sub 

Использование делегата является предпочтительным способом.

+0

, Согласен, но что делать, чтобы сделать пользовательский интерфейс отзывчивым – Sachin

+0

Отредактировано: добавлен правильный код. – Steve

+0

@ Steve.Delegates все сработало..это приятель !!!! – Sachin

0

В основном вы используете поток пользовательского интерфейса с огромным количеством обновлений, чтобы он никогда не получал возможность ответить на ввод пользователя. Измените петлю на сон в течение небольшого промежутка времени.

Do While True 
     Me.ListBox1.Items.Add("Iteration:" & i) 
     i += 1 
     Thread.Sleep(100) 
    Loop 
+0

Я получаю предупреждение возле CurrentThread как «Доступ к общему члену, постоянному члену, перечисляемому члену или вложенному типу через экземпляр; квалификационное выражение не будет оцениваться ». Какая причина – Sachin

+0

Извините, я просто дал это как пример того, что нужно сделать; вам нужно найти способ остановить потребление всего потока пользовательского интерфейса в вашем цикле. Я отредактировал ответ, посмотрим, работает ли это. –

+0

k.this предупреждение было из-за некоторых настроек. Я изменил эти настройки, и это сработало. Ссылка Ref - [Ссылка] http://social.msdn.microsoft.com/Forums/vstudio/en-US/2860692b-eea6-4fe1 -99ef-c53cc6a7f906/access-of-shared-member-constant-member-enum-member-or-nested-type-through-a-instance-qualifying – Sachin

0

При выполнении кода пользовательского интерфейса не отвечает, потому что интерфейс получает огромное количество обновлений в очень короткий промежуток времени, либо остановить цикл из бесконечна:

 Do While True 
      Me.ListBox1.Items.Add("Iteration:" & i) 
      If i > 10 Then 
       Exit Do 
      End If 
      i += 1 
     Loop 

Или добавить таймер ожидания после каждого цикла, чтобы замедлить, как часто пользовательский интерфейс обновляется:

 Do While True 
      Me.ListBox1.Items.Add("Iteration:" & i) 
      i += 1 
      'Sleep for 1 second 
      Thread.CurrentThread.Sleep(1000) 
     Loop 

также вы должны остановить код работает в потоке пользовательского интерфейса, как вы в настоящее время создания потока к n запускать что-то в потоке пользовательского интерфейса, что кажется мне не нужным.

т.е. изменить

Me.InvokeRequired 

Чтобы быть

ListBox1.InvokeRequired 

И

Me.Invoke(New MethodInvoker(AddressOf BackgroundProcess)) 

Чтобы быть

ListBox1.Invoke(New MethodInvoker(AddressOf BackgroundProcess)) 
+0

Спасибо за ваши отзывы. Но мой пользовательский интерфейс остается невосприимчивым. Кнопка «Стоп» не принимает никаких команд. Я хочу остановить этот поток, используя кнопку остановки (t.abort). Могу ли я разбить этот бесконечный цикл while с помощью t.abort () methos – Sachin

+0

Вы можете попробовать создать переменную класса для использования в качестве оператора True и установить ее на false при нажатии кнопки прервать. Однако, если цикл все еще бесконечен и без оператора сна, он все равно приведет к зависанию пользовательского интерфейса, и кнопка «Аборт» не сможет быть нажата. – Nunners

Смежные вопросы