重慶分公司,新征程啟航
為企業提供網站建設、域名注冊、服務器等服務
為企業提供網站建設、域名注冊、服務器等服務
不可以,但是能夠在主線程的基礎上調用委托(Invoke)。(主線程會被占用)
發展壯大離不開廣大客戶長期以來的信賴與支持,我們將始終秉承“誠信為本、服務至上”的服務理念,堅持“二合一”的優良服務模式,真誠服務每家企業,認真做好每個細節,不斷完善自我,成就企業,實現共贏。行業涉及酒樓設計等,在成都網站建設、全網整合營銷推廣、WAP手機網站、VI設計、軟件開發等項目上具有豐富的設計經驗。
例子:
Dim thr As Threading.Thread
Public Delegate Sub VoidDelegate()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
thr = New Threading.Thread(AddressOf Where)
thr.Start()
End Sub
Public Sub Where()
Me.BeginInvoke(New VoidDelegate(AddressOf WhereThr))
End Sub
Public Sub WhereThr()
Me.TextBox.text="0123456789"
End Sub
(Invoke)這種情況下,主線程被占用,所有由主線程執行程序,都將被(wherethr函數執行結束)后執行。
并沒有看出什么地方可能導致程序假死,這排版也太亂了.不妨調試一下程序,當出現你說的"假死"后暫停一下程序,看看線程都卡在哪里.
另外,從設計上來看,你這里并不需要多線程操作.
感覺問題出在
Form2.Show() '啟動倒計時顯示窗口
這一句上。
這一句應該只需要執行一次就行了。
把它放在timer中,多次調用,造成假死。
雖然你的想法是在 LoginBtn_Click 事件中將復雜的操作分離出去以減輕UI的負擔, 這很好完全沒有問題.
但是問題在于 Me.Invoke(dh)這里,若是ChkLogin里面仍然是大規模的操作呢 你的代碼就又變成將很復雜的操作扔給了UI, 當然會出現窗體無法拖動的情況了.
解決辦法很簡單, 很多種. 將ChkLogin()里的操作直接放在DelegateLogin()里面吧 me.invoke僅僅只是做簡單的輕量的刷新之類的操作就好了.
希望能幫上你的忙.
直接添加一個MID父窗體或在已有窗體的屬性中找到IsMDIContainer屬性,然后設置為True,然后創建第二個窗體 ,需要加載子窗體的時候:
Dim NewMDIChild As New Form2
NewMDIChild.MdiParent = Me
NewMDIChild.Show()
Public?Shared?Sub?CheckMDIChildForm(ByVal?MDIForm?As?Windows.Forms.Form,?ByVal?MDIChildForm?As?Windows.Forms.Form,?ByVal?MDIChildFormName?As?String)
If?MDIForm.MdiChildren.Length??1?Then
'如果沒有任何一個MDI子窗體,則創該MDI子窗體的窗體實例
Dim?MDIChildFrm?As?Windows.Forms.Form?=?MDIChildForm?'?定義MDI子窗體
MDIChildFrm.MdiParent?=?MDIForm?'指定父窗體
MDIChildFrm.Show()?'打開窗體
Exit?Sub
Else
Dim?x?As?Integer
Dim?frmyn?As?Boolean
For?x?=?0?To?(MDIForm.MdiChildren.Length)?-?1
Dim?tempChild?As?Windows.Forms.Form?=?CType(MDIForm.MdiChildren(x),?Windows.Forms.Form)
If?tempChild.Name?=?MDIChildFormName?Then
'檢測到有該MDI子窗體,設為激活?并退出循環
frmyn?=?True
tempChild.BringToFront()
Exit?For
Else
frmyn?=?False
End?If
Next
If?Not?frmyn?Then
'在打開的窗體中沒檢測到則新建
Dim?MDIChildFrm?As?Windows.Forms.Form?=?MDIChildForm?'?定義MDI子窗體
MDIChildFrm.MdiParent?=?MDIForm?'指定父窗體
MDIChildFrm.Show()?'打開窗體
End?If
End?If
End?Sub
Imports System.Threading
Public Class Form1
Dim t1, t2 As Thread
Dim tt1
Private Delegate Sub voiddelegate(ByVal i As Integer)
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Form2.Show()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
t1 = New Thread(AddressOf test)
tt1 = 1
t1.Start()
tt1 = 2
t2 = New Thread(AddressOf test)
t2.Start()
' Timer1.Start()
End Sub
Private Sub updateui(ByVal i As Integer)
Form2.Label1.Text = i.ToString
Form2.Label2.Text = i.ToString
End Sub
'把循環放到線程中運行會好一些,其實主要事務是對窗體控件的操作時多線程意義不大,因為訪問窗體的代碼依然要在窗體線程中運行。
Private Sub test()
Dim d As voiddelegate = AddressOf updateui
For i = 0 To 9000
Me.Invoke(d, i)
Next
End Sub
'如果放在計時器中運行效果好的多
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Static i As Integer = 0
i += 1
If i 9000 Then Timer1.Stop() : i = 0
Form2.Label1.Text = i.ToString
Form2.Label2.Text = i.ToString
End Sub
End Class
'如果在另一線程中用Application.run 打開窗體確實能行,不過窗體間相互操作不起作用,這個尚待研究中。