2010-10-04 36 views
5

कार्यक्रम के नीचे देखें। मैं फ़ंक्शन एबीसी के साथ एक नया थ्रेड एक्स शुरू करता हूं, फिर मैं कुछ और कार्य करता हूं। एक्स केवल उप उप के बाद क्यों शुरू होता है? नींद से पहले, इसे तुरंत शुरू नहीं करना चाहिए?मेरा धागा तुरंत क्यों शुरू नहीं हो रहा है?

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     Dim x As New Threading.Thread(AddressOf abc) 
     x.SetApartmentState(Threading.ApartmentState.MTA) 
     x.Start() 

     System.Threading.Thread.Sleep(5000) 
    End Sub 





Sub abc() 
    For i As Integer = 0 To 10 Step 1 
     Me.lblStatus.Text = "Testing DB connection (timeout in: " + i.ToString() + "s)" 
     'Me.StatusStrip1.Invoke(
     MsgBox(i.ToString) 
     System.Threading.Thread.Sleep(1000) 
    Next 
End Sub 



संपादित करें:

(ए) दोनों कनेक्शन प्रयास और अलग धागे में टाइमआउट उलटी गिनती रखो:
समाधान यह है।
(बी) इस तरह यूआई अद्यतन:

If Me.InvokeRequired Then 
     Me.Invoke(pUpdateStatusMessage, "Successfully connected.") 
    Else 
     UpdateStatusMessage("Successfully connected.") 
    End If 
इस के साथ

विश्व स्तर पर घोषित, इसलिए कोई तर्क गुजर आवश्यक है:

Delegate Sub t_pUpdateStatusText(ByVal strMessage As String) 
Public pUpdateStatusMessage As t_pUpdateStatusText = New t_pUpdateStatusText(AddressOf UpdateStatusMessage) 

Public Sub UpdateStatusMessage(ByVal strMessage As String) 
    Me.lblStatus.Text = strMessage 
    Me.StatusStrip1.Update() 
End Sub 
+0

आप कैसे सत्यापित करते हैं कि विधि समाप्त होने के बाद ही धागा शुरू होता है? क्या आप लेबल देख रहे हैं, या आप ब्रेकपॉइंट आग लगने की प्रतीक्षा कर रहे हैं? –

+0

वास्तव में, जब यह प्रदर्शित नहीं हुआ, तो मैंने ब्रेकपॉइंट सेट किया। –

उत्तर

10

abc फ़ंक्शन वास्तव में Button1_Click विधि समाप्त होने से पहले शुरू होगा। क्या भ्रम पैदा कर रहा है 2 बातें

पहले कि आप सीधे निम्न पंक्ति

Me.lblStatus.Text = "Testing DB connection (timeout in: " + i.ToString() + "s)" 

इस कोड गलत है और बाद में समस्याओं का कारण बन सकता है के साथ एक पृष्ठभूमि धागे से यूआई अद्यतन कर रहे है। वास्तव में UI को बदलने के लिए आपको Invoke कॉल का उपयोग करना होगा। जैसा कि आप दूसरी पंक्ति में करते हैं जो हमें अगली समस्या में लाता है।

Invoke कॉल तुल्यकालिक है। यह अनिवार्य रूप से विंडोज संदेश कतार पर एक संदेश को दबाकर और लौटने से पहले संसाधित होने की प्रतीक्षा कर रहा है। Thread.Sleep आपको मुख्य थ्रेड में जोड़ा गया कॉल संदेश संदेश कतार वास्तव में चलने से रोकता है। यह प्रभावी रूप से पृष्ठभूमि धागा को तब तक रोकता है जब तक Sleep कॉल उपस्थिति को पूरा नहीं करता है कि पृष्ठभूमि थ्रेड नहीं चल रहा है।

2

आप एक गैर से अपने यूआई अद्यतन कर रहे हैं यूआई धागा इसकी अनुमति नहीं है, और अजीब व्यवहार का कारण बन सकता है। मुझे नहीं पता कि क्या आपके देरी व्यवहार का कारण बन रहा है, लेकिन आपको पहले इसे हल करने की आवश्यकता होगी।

0

दूसरों के कहने के लिए जोड़ने के लिए, आप अपनी नियंत्रण अद्यतन आवश्यकताओं के हस्ताक्षर को परिभाषित करने के लिए एक प्रतिनिधि बना सकते हैं (इस मामले में, मैं टेक्स्टबॉक्स और स्ट्रिंग मान रहा हूं, लेकिन परिभाषित किया जा सकता है हालांकि आपको आवश्यकता है), और फिर उस विधि का निर्माण करें जो उस प्रतिनिधि हस्ताक्षर का पालन करता है जो आवश्यकता होने पर खुद को अतुल्यकालिक रूप से आमंत्रित करता है।

कुछ इस तरह:

private delegate void ControlUpdateTextHandler(TextBox ctrl, string text); 
public void UpdateControlText(TextBox ctrl, string text) 
{ 
    if (ctrl.InvokeRequired) 
    { 
     ctrl.BeginInvoke((ControlUpdateTextHandler)UpdateControlText, ctrl, text); 
    } 
    else 
     ctrl.Text = text; 
} 

काम करना चाहिए यह 'सही' धागे से कहा जाता है, तो बस पाठ को अपडेट करके (क्योंकि InvokeRequired झूठी इस सूत्र है कि नियंत्रण का मालिक द्वारा कहा जाता है, तो हो सकता है), या यूआई थ्रेड द्वारा किए जाने वाले आमंत्रण को कतारबद्ध करके, "गलत" थ्रेड से (becasue InvokeRequired एक अलग थ्रेड से बुलाया जाएगा)।

0

शायद आपके प्रश्न से संबंधित नहीं है, लेकिन एक अलग थ्रेड से यूआई को अपडेट करने के लिए, मेरा सुझाव है कि आप पृष्ठभूमिवर्कर का उपयोग करें। DoWork में abc() फ़ंक्शन रखें और UI को अपडेट करने के लिए प्रोग्रेस चेंज का उपयोग करें।

संबंधित मुद्दे