Страница: 1 |
Страница: 1 |
Вопрос: Ошибка при создании объектов
Добавлено: 04.04.06 00:13
Автор вопроса: mich | Web-сайт:
Странное дело.
Создаю подпункты меню в коде. При создании в Form_Load работает. А при создании по нажатии на кнопку - itemsов уже нет.
И еще из этой области.
Это работает:
Private Sub tmrRestart_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles tmrRestart.Tick
objWMIService = GetObject("winmgmts:{(Shutdown)}")
'...
А это нет:
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
MyBase.WndProc(m)
Select Case m.Msg
Case 1234
objWMIService = GetObject("winmgmts:{(Shutdown)}")
'...
Ответы
Всего ответов: 15
Номер ответа: 1
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #1
Добавлено: 04.04.06 01:41
Чудес на свете не бывает.. Значит где-то лоханулся.. ищи..
2. А ты на 'Case 1234' Breakpoint повесь и глянь, получаешь ли ты это сообщение вообще? Если да, то попробуй MyBase.WndProc(m) поставить после Select End. Тут возможно такое,что при определенных условиях после MyBase.WndProc(m) управление в процедуру уже не возвращается..
Номер ответа: 2
Автор ответа:
mich
ICQ: 261800349
Вопросов: 19
Ответов: 148
Web-сайт:
Профиль | | #2
Добавлено: 04.04.06 10:23
Да не в этом дело. Все с WndProc в порядке.
"1234" передаю из другой проги.
WndProc отлавливает и выполняет код без проблем.
А вот при создании обьекта прога вылетает.
Причем если мессагу отправляю из этой же проги нажатием на кнопку. Все тоже работает.
Номер ответа: 3
Автор ответа:
mich
ICQ: 261800349
Вопросов: 19
Ответов: 148
Web-сайт:
Профиль | | #3
Добавлено: 05.04.06 10:49
И TreeView в потоке не заполняется.
В ошибке что-то про прерывание в потоке
Номер ответа: 4
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #4
Добавлено: 05.04.06 11:26
Да ты никак Cross-Thread Exeption получил?? Поздравляю!! ) Это знатная ошибка! Если это так, то она сулит тебе много бессонных ночей с MSDN наедине! )) Начинай изучать Delegate, Invoke, InvokeRequired и ознакомься с работой компонента BackgroundWorker (VS 2005).
И советую сразу и подробно разобраться в этом. Поскольку ты работаешь с потоками, то без знания этих вещей тебе не обойтись.
Номер ответа: 5
Автор ответа:
mich
ICQ: 261800349
Вопросов: 19
Ответов: 148
Web-сайт:
Профиль | | #5
Добавлено: 05.04.06 21:45
обрадовал...
Так а прерывание причем?
Номер ответа: 6
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #6
Добавлено: 05.04.06 23:09
Если просто прерывание, то ошибка в твоем коде.. ты сначала прогони его без потока.. А если это то, о чем я выше писал,то ты попал.. ))) но не пугайся.. на самом деле ничего страшного,просто новое это и не обычное.. )))
Номер ответа: 7
Автор ответа:
mich
ICQ: 261800349
Вопросов: 19
Ответов: 148
Web-сайт:
Профиль | | #7
Добавлено: 06.04.06 13:07
Additional information: The action being performed on this control is being called from the wrong thread. You must marshal to the correct thread using Control.Invoke or Control.BeginInvoke to perform this action.
А можно пока примерчик по заполнению treeview в протоке.
Я обещаю что позже разберусь с invoke
Номер ответа: 8
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #8
Добавлено: 06.04.06 15:48
Это не Cross-Thread Exeption.. Так что тебе повезло.. Ищи ошибку в своем коде.. потоки тут не при чем. Ты пока вынеси свой код ЗА пределы потока и отладь его. Я более,чем уверен, что эту же ошибку ты получишь и вне потока.
Номер ответа: 9
Автор ответа:
mich
ICQ: 261800349
Вопросов: 19
Ответов: 148
Web-сайт:
Профиль | | #9
Добавлено: 06.04.06 16:20
Dim t As Threading.Thread
Sub LoadTree()
TreeView1.Nodes.Clear()
For i As Integer = 0 To 10
TreeView1.Nodes.Add("qwe" & i)
Application.DoEvents()
For j As Integer = 0 To 50
TreeView1.Nodes(i).Nodes.Add("wer" & j)
For k As Integer = 0 To 20
TreeView1.Nodes(i).Nodes(j).Nodes.Add("erty" & k)
Next
Next
Next
End Sub
'Входит
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
t = New Threading.Thread(AddressOf LoadTree)
t.Start()
End Sub
'Замечательно выходит !
Private Sub Button2_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
LoadTree()
End Sub
Номер ответа: 10
Автор ответа:
mich
ICQ: 261800349
Вопросов: 19
Ответов: 148
Web-сайт:
Профиль | | #10
Добавлено: 06.04.06 20:09
Ну так что там с Control.Invoke ?
Номер ответа: 11
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #11
Добавлено: 06.04.06 23:48
mich,
Я умышленно не стал делать точную копию твоего примера, а сделал упрощенный вариант, чтобы показать суть того, как это работает. А с передачей Parent Node ты и сам великолепно справишься.
Private t As Threading.Thread
Private Sub LoadTree()
For i As Integer = 0 To 50
AddNode("New Node - " & i)
Next
End Sub
Private Sub AddNode(ByVal NodeText As String)
If TreeView1.InvokeRequired Then
Dim d As New AddNodeCallback(AddressOf AddNode)
TreeView1.Invoke(d, New Object() {NodeText})
Else
TreeView1.Nodes.Add(NodeText)
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TreeView1.Nodes.Clear()
t = New Threading.Thread(AddressOf LoadTree)
t.Start()
End Sub
Номер ответа: 12
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #12
Добавлено: 07.04.06 00:07
И вот еще что.. Обрати внимание на то, что сигнатура у делегата и у процедуры, в которой он используется, должна быть одинаковая.
Номер ответа: 13
Автор ответа:
mich
ICQ: 261800349
Вопросов: 19
Ответов: 148
Web-сайт:
Профиль | | #13
Добавлено: 10.04.06 22:45
Давно не заходил..
сПасиба! А почему просто не работает (без Invoke)?
Номер ответа: 14
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #14
Добавлено: 11.04.06 00:53
С помощью Invoke обеспечивается синхронизация потоков. Через свойство CheckForIllegalCrossThreadCalls можно отключить проверку на CrossThread, но это не есть good! Ошибка генерироваться не будет, и в 90% случаев все будет работать как надо, но в остальных 10% получишь полное зависание программы. Это происходит в тех случаях,когда 2 и более потока пытаются одновременно получить доступ к одному объекту. Например ты записываешь Text в Label, и в этот момент происходит запрос на перерисовку формы где находится этот Label. Вот тут и начнется самое интересное. Так что Invoke жизненно необходим при работе с потоками..
Номер ответа: 15
Автор ответа:
mich
ICQ: 261800349
Вопросов: 19
Ответов: 148
Web-сайт:
Профиль | | #15
Добавлено: 11.04.06 11:20
все ясно