2009-12-21 11 views
5

से एक्सेस वापसी मूल्य मुझे एक प्रोग्राम मिला है जो थ्रेड के माध्यम से एक विधि निष्पादित करता है। स्टार्ट। विधि में एक वापसी मूल्य है जिसे मैं एक्सेस प्राप्त करना चाहता हूं। क्या इसे करने का कोई तरीका है? यहाँ एक नमूना है ...थ्रेड.स्टार्ट() के प्रतिनिधि समारोह

var someValue = ""; 
Thread t = new Thread(delegate() { someValue = someObj.methodCall(); }); 

t.Start(); 

while (t.isAlive) Thread.Sleep(1000); 

// Check the value of someValue 

तो एक बार जबकि पाश समाप्त होता है, someValue सेट किया जाना चाहिए - लेकिन क्योंकि यह एक और धागा में मार डाला है यह सेट प्राप्त करता है। क्या इसका उपयोग करने का कोई आसान तरीका है?

+2

क्या आपने कुछ वैल्यू को 'अस्थिर' घोषित करने का प्रयास किया है? –

+0

भले ही ऐसी सिंक्रनाइज़ेशन तकनीक बहुत अजीब है, यह अस्थिर संशोधक के साथ काम करना चाहिए। Anon –

उत्तर

5

जब कॉलर और थ्रेडेड विधि एक चर साझा करते हैं, तो आपके पास पहले से ही इसका उपयोग होता है - एक बार धागा पूरा होने के बाद, आप बस someValue देखें।

बेशक, आपको यह जानना होगा कि उपयोगी होने के लिए थ्रेडेड विधि कब पूर्ण हो गई है।

  • पिरोया विधि इसके समाप्त होने पर है कि यह निष्पादित कर सकते हैं में एक कॉलबैक भेजें: निचले भाग में, वहाँ यह करने के लिए दो तरीके हैं। आप अपनी कॉलबैक विधि someValue पास कर सकते हैं। कॉलबैक निष्पादित होने पर आप परवाह नहीं करते हैं तो आप इस तकनीक का उपयोग कर सकते हैं।

  • किसी प्रकार के WaitHandle का उपयोग करें (या Thread.Join)। ये आपको बताते हैं कि संसाधन कब तैयार होता है या कोई ईवेंट पूरा हो जाता है। यह तकनीक उपयोगी है यदि आप थ्रेड शुरू करना चाहते हैं, तो कुछ और करें, फिर आगे बढ़ने से पहले थ्रेड पूरा होने तक प्रतीक्षा करें। (दूसरे शब्दों में, यह उपयोगी है अगर आप धागा के साथ वापस समन्वयित करना चाहते हैं न कि केवल सही दूर है,।)

0

Asynchronous Programming Model पर एक नज़र डालें।

मॉडल के वर्णन के सामान्य पैटर्न में से एक में, आपकी कक्षा BeginXXX और EndXXX विधियों का पर्दाफाश करेगी। पूर्व एसिंक्रोनस ऑपरेशन शुरू करता है और एक IAsyncResult ऑब्जेक्ट देता है। उत्तरार्द्ध IAsyncResult ऑब्जेक्ट को तर्क के रूप में स्वीकार करता है, ऑपरेशन पूर्ण होने तक कॉलिंग थ्रेड को अवरुद्ध करता है और आवश्यक मान देता है।

4

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

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    string someValue = ""; 

    private void Form1_Load(object sender, EventArgs e) 
    { 

     Thread t = new Thread(delegate() { someValue = "asdf"; }); 

     t.Start(); 
     t.Join(); 

     //while (t.IsAlive) Thread.Sleep(1000); 

     System.Diagnostics.Debug.Print(someValue); 

    } 
} 
+0

के लिए +1 मैं इसे सोता हूं क्योंकि मुझे उपयोगकर्ता को रद्द करने और थ्रेड को रोकने के लिए सिग्नल करने की आवश्यकता है। – bugfixr

+4

चू: आप जो वर्णन कर रहे हैं वह पृष्ठभूमिवर्कर घटक (यदि आप विंडोज फॉर्म पर हैं) के लिए क्लासिक परिदृश्य है। यह एक समय में एक सेकंड के लिए यूआई थ्रेड सोने से काफी बेहतर है। BackgroundWorker के लिए – itowlson

+0

+1। इसमें निष्पादन प्रगति दिखाने और कार्य को रद्द करने के लिए अंतर्निहित विधियां हैं, इसका उल्लेख न करने के लिए यह निष्पादित होने पर यूआई थ्रेड को लॉक नहीं करेगा। यदि उपयोगकर्ता आपके यूआई थ्रेड पर रद्द बटन दबाता है तो आप पृष्ठभूमि कार्यकर्ता पर ध्वज सेट कर सकते हैं और फिर रद्द कर सकते हैं यह जानने के लिए कि आपके एसिंक कार्य से बाहर निकलने के लिए रद्दीकरण संपत्ति को जांचें। –

1

थ्रेड से मूल्य वापस करने के संभावित तरीकों में से एक पैरामीटर ऑब्जेक्ट के रूप में संदर्भ वर्ग का उपयोग करना है। इसका उपयोग पैरामीटर पास करने और परिणाम को पुनः प्राप्त करने के लिए भी किया जा सकता है।

यदि दूसरी तरफ आप पृष्ठभूमिवर्कर वर्ग का उपयोग कर सकते हैं, तो यह पहले से ही एक समर्पित परिणाम वस्तु है - जो वही काम करता है। लेकिन पृष्ठभूमिवर्कर का उपयोग कुछ उद्देश्यों के लिए नहीं किया जा सकता है (उदाहरण के लिए, यह एसटीए अपार्टमेंट स्टेट का समर्थन नहीं करता है)।

ध्यान रखें कि आपको ctx से पढ़ना नहीं चाहिए। धागा समाप्त होने तक परिणाम (यानी t.IsAlive == false)।

void runThread()   
    { 
     ThreadContext ctx = new ThreadContext(); 
     ctx.Value = 8; 

     Thread t = new Thread(new ParameterizedThreadStart(MyThread)); 
     //t.SetApartmentState(ApartmentState.STA); // required for some purposes 
     t.Start(ctx); 

     // ... 
     t.Join(); 

     Console.WriteLine(ctx.Result); 
    } 

    private static void MyThread(object threadParam) 
    { 
     ThreadContext context = (ThreadContext)threadParam; 

     context.Result = context.Value * 4; // compute result 
    } 

    class ThreadContext 
    { 
     public int Value { get; set; } 
     public int Result { get; set; } 
    } 
0

आप प्रतिनिधि कॉलबैक का उपयोग करके थ्रेड फ़ंक्शन से डेटा पुनर्प्राप्त कर सकते हैं। प्रतिनिधि थ्रेड और कॉलर के बीच एक पुल के रूप में काम कर सकता है। उदाहरण के लिए:

public delegate void DelReturnValue(string value); 
public class SayHello 
{ 
    private string _name; 
    private DelReturnValue _delReturnValue; 

    public SayHello(string name, DelReturnValue delReturnValue) 
    { 
     _name = name; 
     _delReturnValue = delReturnValue; 
    } 

    public void SayHelloMethod() 
    { 
     _delReturnValue(_name); 
    } 
} 

public class Caller 
{ 
    private static string _returnedValue; 
    public static void ReturnValue(string value) 
    { 
     _returnedValue = value; 
    } 

    public static void Main() 
    { 
     DelReturnValue delReturnValue=new DelReturnValue(ReturnValue); 
     SayHello sayHello = new SayHello("test", delReturnValue); 
     Thread newThread = new Thread(new ThreadStart(sayHello.SayHelloMethod)); 
     newThread.Start(); 
     Thread.Sleep(1000); 
     Console.WriteLine("value is returned: " + _returnedValue); 
    } 
} 
संबंधित मुद्दे