2010-07-06 18 views
14

क्या किसी अन्य धागे में वस्तुओं को रखने के लिए सी # में कोई रास्ता है? मैंने पाया कि वास्तव में किसी अन्य धागे में कुछ तरीकों को कैसे निष्पादित करना है। मैं वास्तव में क्या करना चाहता हूं कि किसी ऑब्जेक्ट को बाद में उपयोग किए जाने वाले तरीकों के उपयोग के लिए किसी नए थ्रेड में स्थापित करना है।आप ऑब्जेक्ट को किसी अन्य थ्रेड में कैसे डालते हैं?

आशा है कि आप मेरी मदद कर सकते, रूसो

+0

के रूप में स्थिर –

+14

facepalm @pranay :) – annakata

+0

उपयोग ParameterizedThreadStart अपने धागा करने के लिए एक वस्तु पारित करने के लिए objecta पैदा करते हैं। – Serdar

उत्तर

-1

विधि है कि आप एक सूत्र में चलाने के लिए एक कस्टम वर्ग में रहता है, तो आप इस वर्ग के सदस्यों मापदंडों धारण करने के लिए हो सकता है।

public class Foo 
{ 
    object parameter1; 
    object parameter2; 

    public void ThreadMethod() 
    { 
     ... 
    } 
} 
+0

मैं जानना चाहते हैं आप क्यों downvoted रहे थे। आपका विधि स्वच्छ और समझने में आसान है। मुख्य थ्रेड होगा उस ऑब्जेक्ट के माध्यम से नव निर्मित ऑब्जेक्ट्स तक पहुंच प्राप्त करें जिसमें थ्रेड शुरू हुआ था। साथ ही आपका धागा अन्य धागे के साथ हस्तक्षेप किए बिना ऑब्जेक्ट्स बना सकता है। – diadem

+0

मुझे यह जानना अच्छा लगता है :) –

+0

मुझे लगता है कि यह समाधान बहुत बेवकूफ़ है ऑब्जेक्ट्स धागे से संबंधित नहीं हैं। Objec टीएस स्वयं के जीवन जी रहे हैं। आईएमओ, अगर फू जैसी कक्षा की आवश्यकता है, तो डिजाइन त्रुटियां हैं। – onof

24

ऑब्जेक्ट्स वास्तव में धागे से संबंधित नहीं हैं। यदि आपके पास किसी ऑब्जेक्ट का संदर्भ है, तो आप इसे कई थ्रेड से एक्सेस कर सकते हैं।

इस उद्देश्य यह है कि नहीं बनाया गया है की तरह (लगभग सभी) System.Windows.Forms कक्षाएं, कई धागे से पहुँचा जा करने के लिए, और COM ऑब्जेक्ट के लिए उपयोग के साथ समस्याओं दे सकते हैं।

आप केवल एक ही धागे से एक वस्तु का उपयोग वस्तु में धागा के लिए एक संदर्भ (या एक रैपिंग वस्तु) की दुकान है, और उस धागे के माध्यम से तरीकों पर अमल करना चाहते हैं।

8

एक प्रक्रिया में हिस्सेदारी के सभी थ्रेड एक ही डेटा (धागा स्थानीय भंडारण अनदेखी) तो स्पष्ट रूप से धागे के बीच वस्तुओं विस्थापित करने के लिए कोई जरूरत नहीं है।

internal sealed class Foo 
{ 
    private Object bar = null; 

    private void CreateBarOnNewThread() 
    { 
     var thread = new Thread(this.CreateBar); 

     thread.Start(); 

     // Do other stuff while the new thread 
     // creates our bar. 
     Console.WriteLine("Doing crazy stuff."); 

     // Wait for the other thread to finish. 
     thread.Join(); 

     // Use this.bar here... 
    } 

    private void CreateBar() 
    { 
     // Creating a bar takes a long time. 
     Thread.Sleep(1000);    

     this.bar = new Object(); 
    } 
} 
2

सभी सूत्र, ढेरढेर देख सकते हैं, इसलिए यदि धागा (उदाहरण के लिए, एक विधि के माध्यम से में पारित) वस्तुओं की जरूरत के लिए एक संदर्भ है तो धागा उन वस्तुओं का उपयोग कर सकते हैं। यही कारण है कि आपको बहु-थ्रेडिंग के दौरान ऑब्जेक्ट्स तक बहुत सावधान रहना होगा, क्योंकि दो थ्रेड एक ही समय में ऑब्जेक्ट को आजमा सकते हैं और बदल सकते हैं। http://msdn.microsoft.com/en-us/library/dd642243.aspx और http://www.c-sharpcorner.com/UploadFile/ddoedens/UseThreadLocals11212005053901AM/UseThreadLocals.aspx

+3

"सभी धागे ढेर देख सकते हैं": नहीं ... प्रत्येक धागा अपने * अपने * ढेर को देख सकता है। लेकिन सभी धागे ढेर को देख सकते हैं, हालांकि। –

+0

मेरी गलती। उलझन में ढेर और ढेर - क्या शुरुआत करने वाला गलती है! :( –

1

उपयोग ParameterizedThreadStart अपने धागा करने के लिए एक वस्तु पारित करने के लिए देखें:

.NET में एक ThreadLocal<T> वर्ग है कि आप एक विशिष्ट थ्रेड के लिए चर प्रतिबंधित करने के लिए उपयोग कर सकते हैं नहीं है।

0

"बाद में उपलब्ध विधियों के उपयोग के लिए।"

नए धागे और अन्य डेटा और विधियों पर निष्पादित करने के लिए विधि वाली कक्षा का उपयोग करके, आप अपने थ्रेड से डेटा और नए थ्रेड से विधियों तक पहुंच प्राप्त कर सकते हैं।

लेकिन ... यदि आप कक्षा से एक विधि निष्पादित करते हैं, तो आप वर्तमान धागे पर निष्पादित कर रहे हैं।

नए थ्रेड पर विधि को निष्पादित करने के लिए कुछ थ्रेड सिंक्रनाइज़ेशन की आवश्यकता है।

System.Windows.Forms.Control.BeginInvoke यह, नियंत्रण धागा जब तक एक अनुरोध आता है इंतज़ार कर रहा है है।

WaitHandle वर्ग आप कर सकते हैं।

12

वहाँ कैसे धागे यहाँ काम करने के लिए के रूप में कुछ भ्रम की स्थिति होने लगते हैं, तो यह एक प्राइमर है (भी बहुत ही कम है, तो आप मल्टी-थ्रेडेड प्रोग्रामिंग में आगे करने से पहले अधिक सामग्री मिलनी चाहिए।)

वस्तुओं और स्मृति अंतर्निहित बहु-धागे इस अर्थ में है कि एक प्रक्रिया में सभी धागे उन्हें चुन सकते हैं जैसे वे चुनते हैं।

इसलिए वस्तुओं के धागे के साथ कुछ भी नहीं है।

हालांकि, कोड थ्रेड में निष्पादित होता है, और यह कोड उस थ्रेड को निष्पादित करता है जिसमें आप शायद बाद में होते हैं।

दुर्भाग्यवश, "ऑब्जेक्ट को एक अलग थ्रेड में डालने" का कोई तरीका नहीं है, जैसा कि आप इसे डालते हैं, आपको विशेष रूप से थ्रेड शुरू करना होगा और उस थ्रेड में निष्पादित करने के लिए कोड निर्दिष्ट करना होगा। उस कोड द्वारा उपयोग किए जाने वाले ऑब्जेक्ट्स को इस धागे से संबंधित "कहा" कहा जा सकता है, हालांकि यह एक कृत्रिम सीमा है जिसे आप स्वयं लगाते हैं।

तो वहाँ यह करने के लिए कोई रास्ता नहीं है:

SomeObject obj = new SomeObject(); 
obj.PutInThread(thatOtherThread); 
obj.Method(); // this now executes in that other thread 

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

Thread 1: 
    SomeObject obj = new SomeObject(); 

Thread 2: 
    obj.Method(); // executes in Thread 1 

विधि यहाँ थ्रेड 2 में मूल सूत्र में निष्पादित करने के लिए विधि प्राप्त करने के लिए एक ही रास्ता निष्पादित करेंगे मूल थ्रेड के साथ सहयोग और करने के लिए है "से पूछते हैं:

तो निम्नलिखित भी सही नहीं है यह "उस विधि को निष्पादित करने के लिए। आप कैसे करते हैं यह स्थिति पर निर्भर करता है और ऐसा करने के कई तरीके हैं।

तो आप जो चाहते हैं उसे सारांशित करने के लिए: आप एक नया धागा बनाना चाहते हैं, और उस थ्रेड में कोड निष्पादित करना चाहते हैं।

ऐसा करने के लिए, Thread .NET की कक्षा देखें।

लेकिन चेतावनी दी: बहु पिरोया अनुप्रयोगों निहायत सही पाने के लिए कड़ी मेहनत कर रहे हैं, मैं एक कार्यक्रम के लिए मल्टी-थ्रेडेड क्षमताओं नहीं जोड़ना होगा, जब तक कि:

  1. इसे से बाहर और अधिक प्रदर्शन प्राप्त करने के लिए एक ही रास्ता है कि
  2. और, आप जानते हैं कि आप क्या कर रहे हैं
0

कुछ पिछले काम नकल करने क्षमा करें, लेकिन ओ पी ने कहा

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

क्या मैं वास्तव में क्या करना चाहते हैं एक नया धागा एक वस्तु का दृष्टांत ताकि बाद में मुझे लगता है कि वस्तु के तरीकों का उपयोग कर सकते है:

मुझे व्याख्या के रूप में है कि करते हैं।

अगर मुझे निशान याद आया तो मुझे सही करें। यहां उदाहरण दिया गया है:

namespace silly 
{ 
    public static class Program 
    { 
     //declared volatile to make sure the object is in a consistent state 
     //between thread usages -- For thread safety. 
     public static volatile Object_w_Methods _method_provider = null; 
     static void Main(string[] args) 
     { 
      //right now, _method_provider is null. 
      System.Threading.Thread _creator_thread = new System.Threading.Thread(
       new System.Threading.ThreadStart(Create_Object)); 
      _creator_thread.Name = "Thread for creation of object"; 
      _creator_thread.Start(); 

      //here I can do other work while _method_provider is created. 
      System.Threading.Thread.Sleep(256); 

      _creator_thread.Join(); 

      //by now, the other thread has created the _method_provider 
      //so we can use his methods in this thread, and any other thread! 

      System.Console.WriteLine("I got the name!! It is: `" + 
       _method_provider.Get_Name(1) + "'"); 

      System.Console.WriteLine("Press any key to exit..."); 
      System.Console.ReadKey(true); 

     } 
     static void Create_Object() 
     { 
      System.Threading.Thread.Sleep(512); 
      _method_provider = new Object_w_Methods(); 
     } 
    } 
    public class Object_w_Methods 
    { 
     //Synchronize because it will probably be used by multiple threads, 
     //even though the current implementation is thread safe. 
     [System.Runtime.CompilerServices.MethodImpl( 
      System.Runtime.CompilerServices.MethodImplOptions.Synchronized)] 
     public string Get_Name(int id) 
     { 
      switch (id) 
      { 
       case 1: 
        return "one is the name"; 
       case 2: 
        return "two is the one you want"; 
       default: 
        return "supply the correct ID."; 
}}}} 
0

बस पिछले उत्तर पर विस्तृत करना चाहते हैं। समस्या पर वापस जाने के लिए, ऑब्जेक्ट्स और मेमोरी स्पेस सभी थ्रेड द्वारा साझा किए जाते हैं। इसलिए वे हमेशा साझा होते हैं, लेकिन मुझे लगता है कि आप इतना सुरक्षित करना चाहते हैं और किसी अन्य धागे द्वारा बनाए गए परिणामों के साथ काम करना चाहते हैं।

सबसे पहले विश्वसनीय सी # पैटर्न में से किसी एक को आजमाएं। Async Patterns साथ काम करने के लिए सेट पैटर्न हैं, जो थ्रेड के बीच मूल संदेश और डेटा संचारित करते हैं। आमतौर पर परिणाम की गणना करने के बाद एक खतरा पूरा हो जाता है!

जीवन खतरे: जीवन के खतरों पर अतुल्यकालिक और डेटा साझा करते समय मूर्खतापूर्ण प्रमाण कुछ भी नहीं है। तो मूल रूप से इसे यथासंभव सरल रखें यदि आपको इस मार्ग पर जाने की आवश्यकता है और ज्ञात पैटर्न का पालन करने की आवश्यकता है।

EventArgs: जहाँ आप इसे पारित करने से पहले वस्तुओं की एक deepcopy बनाने

तो अब मैं सिर्फ विस्तृत करने क्यों जाना जाता patters से कुछ एक निश्चित संरचना है पसंद है। (यह मूर्खतापूर्ण नहीं है क्योंकि कुछ संदर्भ अभी भी साझा किए जा सकते हैं।) इंट फ्लोट आदि जैसे मूल प्रकारों के साथ परिणाम पास करना, इन्हें एक कन्स्ट्रक्टर पर बनाया जा सकता है और अपरिवर्तनीय बना दिया जा सकता है।

परमाणु कुंजी शब्द इन प्रकारों, या मॉनीटर आदि बनाते हैं .. एक धागे पर चिपकें अन्य लिखते हैं।

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

एक और तरीका जो मदद करता है F # प्रोग्राम करना है। वहां ऑब्जेक्ट्स और सभी प्रकार डिफ़ॉल्ट रूप से अपरिवर्तनीय होते हैं/इसलिए आपकी ऑब्जेक्ट्स जिन्हें आप साझा करना चाहते हैं, में एक कन्स्ट्रक्टर होना चाहिए और ऑब्जेक्ट को बदलने या बुनियादी प्रकारों को बढ़ाने के लिए कोई भी तरीका नहीं होना चाहिए। तो आप उन्हें बनाते हैं और फिर वे नहीं बदलते हैं! तो वे उसके बाद गैर परिवर्तनीय हैं। उन्हें लॉक कर देता है और समानांतर में उनके साथ काम करना इतना आसान बनाता है। सी # कक्षाओं में इसके साथ पागल मत बनो क्योंकि अन्य लोग इस "सम्मेलन" का पालन कर सकते हैं और अधिकांश चीजें जैसे कि लिस्ट को सी # में अपरिवर्तनीय बनाने के लिए डिज़ाइन नहीं किया गया था (केवल पढ़ने के लिए अपरिवर्तनीय नहीं है, कॉन्स है लेकिन यह बहुत सीमित है)। Immutable versus readonly

+0

इस जवाब के बारे में कुछ खतरनाक है ... – Nyerguds

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