2012-03-08 15 views
5

मेरे पास एक छोटा सा एप्लीकेशन है जिसे कई कनेक्शनों के लिए एसक्यूएल कनेक्शन स्ट्रिंग का परीक्षण करने की आवश्यकता है (प्रत्येक एक-एक-एक-एक समय में किया जाता है)। ऐसा करने के लिए, यदि कनेक्शन मान्य नहीं है और ConnectionTimeout = 0 (हमेशा के लिए प्रतीक्षा करें), तो लंबे समय से प्रतीक्षा करने के लिए अस्थायी रूप से ConnectionTimeout = 5 सेट करें।टीपीएल 'कॉल-बैक' कैसे करें

जबकि हम Open() करने का प्रयास खराब कनेक्शन (यहां तक ​​कि ConnectionTimeout = 5 साथ SqlException के लिए प्रतीक्षा करने के लिए बीस सेकंड हो सकता है) यूआई फांसी से बचने के लिए, मैं एक अलग थ्रेड टास्क समानांतर लाइब्रेरी का उपयोग पर परीक्षण चलाना चाहते हैं (TPL)। इसलिए मैं स्पिन बंद मेरी नई धागे की तरह:

Task<bool> asyncTestConn = Task.Factory.StartNew<bool> 
    (() => TestConnection(conn, bShowErrMsg)); 
return asyncTestConn.Result; 

समस्या यह है कि यह अभी भी, यूआई (स्पष्ट रूप से) ताला लगा है के रूप में यह फोन करने वाले पर लौटने से पहले परिणाम के लिए इंतजार कर रहा है। एसिंक्रोनस Task से अंतिम परिणाम प्राप्त करते समय मैं कोड को UI पर नियंत्रण वापस करने की अनुमति कैसे दूंगा (जीयूआई को मुक्त करना)?

इसके अलावा, Task के भीतर से मैं वैध रूप से MessageBox.Show("Some message") कर सकता हूं? यह BackgroundWorkers के लिए काम नहीं करता है और यह पूल-थ्रेड डिफ़ॉल्ट रूप से पृष्ठभूमि थ्रेड है; फिर भी यह एक समस्या प्रतीत नहीं होता है। आपके समय के लिए धन्यवाद।

उत्तर

4

आप ठीक कह रहे हैं, यह वह जगह है जहाँ प्रतीक्षा होता है:

return asyncTestConn.Result; 

आप बस) TestConnection (की पूंछ में खत्म-अप कोड का निर्माण या एक निरंतरता इस्तेमाल कर सकते हैं:

// untested 
//Task<bool> asyncTestConn = Task.Factory.Create<bool> (
Task<bool> asyncTestConn = new Task<bool> (
    () => TestConnection(conn, bShowErrMsg)); 
asyncTestConn.ContinueWith(MyFinishCode); 
asyncTestConn.Start() 

क्या मैं वैध रूप से MessageBox.Show("Some message") कर सकता हूं?

असल में हाँ, संदेशबॉक्स थ्रेड-सुरक्षित है। बीजीडब्ल्यू से भी संभव होना चाहिए।

लेकिन आप कार्य के जीवन को बहुत लंबे समय तक बढ़ा रहे हैं, यह एक अच्छा विचार नहीं है।

+0

आपकी प्रतिक्रिया के लिए बहुत बहुत धन्यवाद। पूरा विचार यूआई/जीयूआई को जितनी जल्दी हो सके पास वापस नियंत्रण प्राप्त करना है, उपरोक्त कैसे प्राप्त/प्राप्त कर सकते हैं? अगर मैं उपरोक्त कोड को 'ParrTestConn (SqlConnection conn, string bShowErrMsg) नामक विधि से कॉल कर रहा हूं, तो मैं 'asyncTestConn.ContinueWith (ParrTestConn (conn, bShowErrMsg)) नहीं कह सकता ... या मैं कर सकता हूं? – MoonKnight

+0

@ किलर आप बस स्टार्ट() के बाद वापस आ सकते हैं। इसका उपयोग करते समय जीयूआई को उत्तरदायी रहना चाहिए। –

+0

मेरे पास 'Task.Factory.Create 'विधि उपलब्ध नहीं है? – MoonKnight

5

टीपीएल के लिए, ContinueWith वही है जो आप चाहते हैं। हेनक के उत्तर पर विस्तार:

var asyncTestConn = Task.Factory.StartNew(() => TestConnection(conn, bShowErrMsg)); 
// Henk's "MyFinishCode" takes a parameter representing the completed 
// or faulted connection-testing task. 
// Anything that depended on your "return asyncTestConn.Result;" statement 
// needs to move into the callback method. 
asyncTestConn.ContinueWith(task => 
    { 
     switch (task.Status) 
     { 
      // Handle any exceptions to prevent UnobservedTaskException. 
      case TaskStatus.Faulted: /* Error-handling logic */ break; 
      case TaskStatus.RanToCompletion: /* Use task.Result here */ break; 
     } 
    }, 
    // Using this TaskScheduler schedules the callback to run on the UI thread. 
    TaskScheduler.FromCurrentSynchronizationContext()); 
+0

वास्तव में सहायक। धन्यवाद। दो उत्तरों का संयोजन बिल्कुल टकसाल है। – MoonKnight

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