পরামিতি সহ থ্রেডস্টার্ট


261

আপনি কীভাবে সি # তে পরামিতি দিয়ে একটি থ্রেড শুরু করবেন?


এই প্রশ্নের উত্তর রানটাইমের বিভিন্ন সংস্করণে বিভিন্নভাবে পরিবর্তিত হয় - একটি 3.5 উত্তর জরিমানা?
কুইলব্রেকার

4
কি দারুন. আমি আপনার কিছু পুরানো প্রশ্ন সম্পাদনা করছি, তবে এটি একটি পুরো সময়ের কাজ হতে পারে। আমি ভুলে গিয়েছিলাম, আহা, কয়েক বছরে আপনি কতটা উন্নতি করেছেন। :-)
জন Saunders

আমি যদি এইরকম একটি সংক্ষিপ্ত প্রশ্ন জিজ্ঞাসা করি তবে আমি 5 টি নেতিবাচক স্কোর বা তারও বেশি পেতে পারি! যদিও প্রশ্নোত্তর আমাকে সাহায্য করেছিল।
মোহাম্মদ মুসাভি

উত্তর:


174

হ্যাঁ:

Thread t = new Thread (new ParameterizedThreadStart(myMethod));
t.Start (myParameterObject);

14
এটি কি একই: থ্রেডস্টার্ট প্রক্রিয়াটাস্কথ্রেড = প্রতিনিধি {প্রসেসটাস্কস (ডেটাবক্স.ডাটাবক্সআইডি); }; নতুন থ্রেড (প্রসেসটাস্কথ্রেড)। স্টার্ট ();
জেএল।

43
মাইপ্রামঅবজেক্ট এবং মাইআরএল কী?
ডায়ালেক্স

3
এই ক্ষেত্রে void MyParamObject(object myUrl){ //do stuff }প্যারামিটারের ধরণ থাকতে হবেobject
এলশান

15
-1 কারণ উত্তরটি ধরে নিয়েছে যে ParameterizedThreadStartপ্রশ্নটি পাঠ্য থেকে ওপি কীভাবে ব্যবহার করতে এবং স্পষ্টভাবে জানে , সম্ভবত এটি নয়।
জেলটন

2
আমার এই ত্রুটিটি CS0123 এ আছে 'আপডেটডিবি'র সাথে' প্যারামিটারাইজড ট্র্যাড স্টার্ট 'ডেলিগেটের মিল নেই
ওমিদ ফারভিদ

482

থ্রেড কনস্ট্রাক্টরের 2 টি ওভারলোডগুলির মধ্যে একটি প্যারামিটারাইজড থ্রেডস্টার্ট ডেলিগেটকে নেয় যা আপনাকে প্রারম্ভিক পদ্ধতিতে একটি একক প্যারামিটার পাস করতে দেয়। দুর্ভাগ্যক্রমে যদিও এটি কেবলমাত্র একটি একক প্যারামিটারের জন্য অনুমতি দেয় এবং এটি এটি অনিরাপদভাবে করে কারণ এটি এটিকে অবজেক্ট হিসাবে পাস করে। আমি প্রাসঙ্গিক পরামিতিগুলি ক্যাপচার করতে এবং একটি দৃ typ়ভাবে টাইপ করা ফ্যাশনে তাদের পাস করার জন্য ল্যাম্বডা এক্সপ্রেশনটি ব্যবহার করা অনেক সহজ easier

নিম্নলিখিত চেষ্টা করুন

public Thread StartTheThread(SomeType param1, SomeOtherType param2) {
  var t = new Thread(() => RealStart(param1, param2));
  t.Start();
  return t;
}

private static void RealStart(SomeType param1, SomeOtherType param2) {
  ...
}

41
+1: যদিও বর্তমানে নির্বাচিত উত্তরগুলি একেবারে সঠিক, জারেডপাড়ের এই উত্তরটি আরও ভাল। এটি কেবল বেশিরভাগ ব্যবহারিক ক্ষেত্রে সবচেয়ে ভাল সমাধান।
galaktor

2
এই সমাধান অনেক ভালো তারপর standrard ParameterizedThreadStart হয়
পাযত্র Owsiak

5
খুব সহজ। "নতুন থ্রেড (() => ফুবার ()) এ যে কোনও কল কেবল জড়ান art স্টার্ট ();
টমাস জেস্পারসেন

12
দুর্দান্ত, এটি VB.NET ছেলেদের জন্যDim thr As New Thread(Sub() DoStuff(settings))
ডা। খারাপ

3
@ বাজাজা আমি কেবল স্থির ধরণের চেকিং
জারেডপাড়

141

আপনি ল্যাম্বদা এক্সপ্রেশন ব্যবহার করতে পারেন

private void MyMethod(string param1,int param2)
{
  //do stuff
}
Thread myNewThread = new Thread(() => MyMethod("param1",5));
myNewThread.Start();

এটি এখন পর্যন্ত সবচেয়ে ভাল উত্তর আমি খুঁজে পেতে পারি, এটি দ্রুত এবং সহজ।


6
সাধারণ মামলার সেরা সমাধান আইএমও
ডানক

1
এটা কি =>? এবং সিনট্যাক্স সম্পর্কে আরও তথ্য কোথায় পাব?
নিক

2
এটি ল্যাম্বডা এক্সপ্রেশন, এই ঠিকানাগুলিতে কিছু তথ্য পাওয়া যাবে: এমএসডিএন.ইমক্রিফ্টস /en-us/library/vstudio/bb397687.aspx | কোডেপ্রজেক্ট / আর্টিকেলগুলি / 24255/ এক্সপ্লোরিং- ল্যাম্বদা- এক্সপ্রেশন- ইন- সি | dotnetperls.com/lambda
জর্জি-

1
এটি আমার পক্ষে কাজ করেছে। আমি প্যারামিটারাইজড থ্রেড স্টার্ট এবং এর বিভিন্নতা চেষ্টা করেছিলাম তবে কোনও আনন্দ হয়নি। আমি অনুমিত একটি সহজ কনসোল অ্যাপ্লিকেশনে। নেট ফ্রেমওয়ার্ক 4 ব্যবহার করছিলাম।
ড্যানিয়েল হোলিনরাকে 12

এটি এমন ব্যক্তির পক্ষে সবচেয়ে ভাল কাজ করে যারা এই ধরণের প্রতিনিধিদের অভ্যস্ত। নবীনদের পক্ষে উডারস্ট্যান্ড করা কঠিন হতে পারে। যদিও এটি সি # স্ট্যান্ডার্ডের জন্য পরিষ্কার। গৃহীত উত্তরটি আমার পক্ষে কার্যকর নয় এবং কেন তা জানার আমার কাছে সময় নেই।
বিটারব্লিউ

37
Thread thread = new Thread(Work);
thread.Start(Parameter);

private void Work(object param)
{
    string Parameter = (string)param;
}

পরামিতি প্রকারটি অবশ্যই একটি অবজেক্ট হতে হবে।

সম্পাদনা করুন:

যদিও এই উত্তরটি ভুল নয় তবে আমি এই পদ্ধতির বিরুদ্ধে প্রস্তাব দিই। ল্যাম্বডা এক্সপ্রেশন ব্যবহার করা পড়া সহজ এবং প্রকারের ingালাইয়ের প্রয়োজন হয় না। এখানে দেখুন: https://stackoverflow.com/a/1195915/52551


আপনি এমন একটি কোড কেন সাহায্য করছেন যা সংকলন করে না;) Parameter?
সেবাস্তিয়ান জাওরি ওয়াইনিওইইকি

32
class Program
{
    static void Main(string[] args)
    {
        Thread t = new Thread(new ParameterizedThreadStart(ThreadMethod));

        t.Start("My Parameter");
    }

    static void ThreadMethod(object parameter)
    {
        // parameter equals to "My Parameter"
    }
}

3
এটি আমাকে "ডুওয়ার্ক 'ম্যাচের জন্য' ওভারলোডের জন্য 'ডেলিগেট' সিস্টেম। থ্রেডিং.প্রেমেটারাইজড ট্র্যাড স্টার্ট '
anon58192932

1
থ্রেড টি ইনিশিয়ালেশনে আপনি যদি থ্রেডমেথোদ পাস করেছেন তবে কী পার্থক্য হবে?
জো

মনে রাখবেন, প্যারামিটারের ধরনটি 'অবজেক্ট' প্রকারের হতে হবে
কুনাল উৎপল

28

লম্বদা ব্যবহারের মতো সহজ উপায় ..

Thread t = new Thread(() => DoSomething("param1", "param2"));
t.Start();

অথবা আপনি এমনকি এর মতো delegateব্যবহার করতে ThreadStartপারেন ...

ThreadStart ts = delegate
{
     bool moreWork = DoWork("param1", "param2", "param3");
     if (moreWork) 
     {
          DoMoreWork("param4", "param5");
     }
};
new Thread(ts).Start();

বা ভিএস 2019 ব্যবহার করুন। নেট 4.5+ এমনকি এমন আরও ক্লিনার ব্যবহার করুন ..

private void DoSomething(int param1, string param2)
{
    //DO SOMETHING..
    void ts()
    {
        if (param1 > 0) DoSomethingElse(param2, "param3");
    }
    new Thread(ts).Start();
    //DO SOMETHING..
}



6

ইতিমধ্যে এখানে বিভিন্ন Threadউত্তরে উল্লেখ করা হয়েছে যে ক্লাসটি বর্তমানে (৪.7.২) বিভিন্ন নির্মাণকারী এবং Startওভারলোড সহ একটি পদ্ধতি সরবরাহ করে।

এই প্রশ্নের জন্য এই প্রাসঙ্গিক নির্মাতারা হলেন:

public Thread(ThreadStart start);

এবং

public Thread(ParameterizedThreadStart start);

যা হয় একটি ThreadStartপ্রতিনিধি বা একটি ParameterizedThreadStartপ্রতিনিধি গ্রহণ।

সংশ্লিষ্ট প্রতিনিধিরা এর মতো দেখায়:

public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(object obj);

যেমন দেখা যায়, সঠিকভাবে নির্মাণকারীর ব্যবহারকারীর ParameterizedThreadStartপ্রতিনিধি নিচ্ছেন বলে মনে হচ্ছে যাতে কোনও পদ্ধতি ডেলিগেটের নির্দিষ্ট স্বাক্ষর অনুসারে থ্রেডের সাহায্যে শুরু করা যায়।

Threadক্লাসটি ইনস্ট্যান্ট করার জন্য একটি সাধারণ উদাহরণ হবে

Thread thread = new Thread(new ParameterizedThreadStart(Work));

বা শুধু

Thread thread = new Thread(Work);

সংশ্লিষ্ট পদ্ধতির স্বাক্ষর ( Workএই উদাহরণে বলা হয়) এর মতো দেখায়:

private void Work(object data)
{
   ...
}

যা বাকি তা থ্রেড শুরু করা। এটি হয় ব্যবহার করে করা হয়

public void Start();

অথবা

public void Start(object parameter);

যদিও Start()থ্রেড শুরু করা এবং পাস হবে nullপদ্ধতিতে ডেটা, Start(...)পাস ব্যবহার করা যেতে পারে কিছু মধ্যে Workথ্রেডের পদ্ধতি।

এই পদ্ধতির সাথে তবে একটি বড় সমস্যা রয়েছে: Workপদ্ধতিতে পাস করা সমস্ত কিছু একটি বস্তুতে ফেলে দেওয়া হয়। তার মানে হল যে Workপদ্ধতিটির মধ্যে এটিকে আবার নিম্নলিখিত ধরণের মতো আবার মূল ধরণে ফেলে দিতে হবে:

public static void Main(string[] args)
{
    Thread thread = new Thread(Work);

    thread.Start("I've got some text");
    Console.ReadLine();
}

private static void Work(object data)
{
    string message = (string)data; // Wow, this is ugly

    Console.WriteLine($"I, the thread write: {message}");
}



কাস্টিং এমন একটি জিনিস যা আপনি সাধারণত করতে চান না।

যদি কেউ অন্য কিছু পাস করে যা স্ট্রিং নয়? যেহেতু এটি প্রথমে সম্ভব নয় বলে মনে হয় (কারণ এটি আমার পদ্ধতি, আমি জানি আমি কী করি বা পদ্ধতিটি ব্যক্তিগত, তাই কোনও ব্যক্তির কীভাবে কোনও কিছুতে এটি পাস করা কখনই সক্ষম হওয়া উচিত? ) বিভিন্ন কারণে আপনি সম্ভবত ঠিক সেই ক্ষেত্রেই শেষ করতে পারেন । কিছু ক্ষেত্রে সমস্যা নাও হতে পারে, অন্যরা হ'ল are এই ধরনের ক্ষেত্রে আপনি সম্ভবত InvalidCastExceptionএমনটি দিয়ে শেষ করবেন যা আপনি সম্ভবত লক্ষ্য করবেন না কারণ এটি কেবল থ্রেডটি বন্ধ করে দেয়।

একটি সমাধান হিসেবে আপনি একটি জেনেরিক পেতে আশা ParameterizedThreadStartমত প্রতিনিধি ParameterizedThreadStart<T>যেখানে Tআপনি মধ্যে পাস করতে চান ডেটার প্রকারের হবে Workপদ্ধতি। দুর্ভাগ্যক্রমে এর মতো কিছু বিদ্যমান নেই (এখনও?)।

তবে এই ইস্যুটির একটি প্রস্তাবিত সমাধান রয়েছে । এটিতে এমন একটি শ্রেণি তৈরি করা রয়েছে যাতে উভয়ই থাকে, ডাটাটি থ্রেডে পাঠানো হয় এবং সেই পদ্ধতিটি যা শ্রমিকের পদ্ধতিটিকে এভাবে প্রতিনিধিত্ব করে:

public class ThreadWithState
{
    private string message;

    public ThreadWithState(string message)
    {
        this.message = message;
    }

    public void Work()
    {
        Console.WriteLine($"I, the thread write: {this.message}");
    }
}

এই পদ্ধতির সাহায্যে আপনি থ্রেডটি এভাবে শুরু করবেন:

ThreadWithState tws = new ThreadWithState("I've got some text");
Thread thread = new Thread(tws.Work);

thread.Start();

সুতরাং এই উপায়ে আপনি কেবল চারপাশে ingালাই এড়ানো এবং কোনও থ্রেডে ডেটা সরবরাহ করার একটি টাইপসেজ উপায় আছে ;-)


বাহ, কোনও মন্তব্য ছাড়াই একটি নিম্নগঠন ... হয় আমার উত্তরটি কাস্টের মতো খারাপ বা পাঠক বুঝতে পারেনি আমি এখানে কী উল্লেখ করার চেষ্টা করেছি ;-)
মার্কাস সাফার

1
আমি আপনার সমাধানটি খুব আলোকিত করেছি, অভিনন্দন জানাচ্ছি। কেবলমাত্র যুক্ত করতে চেয়েছিলাম যে আমি ইতিমধ্যে নেট.কোরে পরীক্ষা করেছি এবং স্পষ্টতা কাস্ট না করে কাজ করেছি! :-) private static void MyMethod<T>(T myData) { T message = myData; Console.WriteLine($"the thread wrote: {message}"); }
পল এফর্ড

@ পলএফর্ড ধন্যবাদ ;-) আপনার সমাধানটি বেশ সুন্দর বলে মনে হচ্ছে। তবে আপনি নির্দিষ্ট তথ্য টাইপ করতে অ্যাক্সেস পান না কেননা এটি এখনও কোনও বস্তুর সাথে বাক্স হবে, তাই না? (উদাঃ message.Lengthসম্ভব নয় ইত্যাদি)
মার্কাস সাফার 14

1
ডান ... আপনি বার্তা দিতে পারেন.গেটটাইপ () এবং যদি কোনও নির্দিষ্ট সম্পত্তি যেমন প্রয়োজন হয় তবে কাস্ট করতে পারেন if(myData.GetType() == typeof(string)) { var str = ((string)(object)myData).Length; }। যাই হোক, এর পরিবর্তে আপনার থ্রেডিং পদ্ধতি ব্যবহার করে আমি একটি বিট আরো ব্যবহার করতে আরামদায়ক পাওয়া Tasks<T>, মত উদাহরণস্বরূপ tasks.Add(Task.Run(() => Calculate(par1, par2, par3))), নীচের আমার উত্তর (দেখুন stackoverflow.com/a/59777250/7586301 )
পল Efford

5

উত্তীর্ণ প্যারামিটারে আমার সমস্যা ছিল। আমি একটি লুপ থেকে ফাংশনটিতে পূর্ণসংখ্যার পাস করেছি এবং এটি প্রদর্শন করেছি, তবে এটি সর্বদা ভিন্ন ফলাফল দেয়। যেমন (1,2,2,3) (1,2,3,3) (1,1,2,3) ইত্যাদি প্যারামেট্রাইজড ট্র্যাডস্টার্ট প্রতিনিধি সহ।

এই সাধারণ কোডটি কবজ হিসাবে কাজ করেছিল

Thread thread = new Thread(Work);
thread.Start(Parameter);

private void Work(object param) 
{
 string Parameter = (string)param; 
}

4

ParameterizedThreadStartএক পরামিতি গ্রহণ করে। আপনি এটি ব্যবহার করতে পারেন একটি প্যারামিটার পাঠাতে, বা একটি কাস্টম ক্লাস যা বেশ কয়েকটি বৈশিষ্ট্যযুক্ত।

আরেকটি পদ্ধতি হ'ল আপনি যে প্যারামিটারগুলি সেট করতে চান তার বৈশিষ্ট্য সহ ক্লাসে উদাহরণস্বরূপ সদস্য হিসাবে যে পদ্ধতিটি শুরু করতে চান তা স্থাপন করা। শ্রেণীর একটি উদাহরণ তৈরি করুন, বৈশিষ্ট্যগুলি সেট করুন এবং উদাহরণ এবং পদ্ধতিটি উল্লেখ করে থ্রেড শুরু করুন এবং পদ্ধতিটি বৈশিষ্ট্যগুলিতে অ্যাক্সেস করতে পারে।




1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace ConsoleApp6
{
    class Program
    {
        static void Main(string[] args)
        {

            int x = 10;
            Thread t1 =new Thread(new ParameterizedThreadStart(order1));
            t1.IsBackground = true;//i can stope 
            t1.Start(x);

            Thread t2=new Thread(order2);
            t2.Priority = ThreadPriority.Highest;
            t2.Start();

            Console.ReadKey();
        }//Main

        static void  order1(object args)
        {
            int x = (int)args;


                for (int i = 0; i < x; i++)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.Write(i.ToString() + " ");
            }
        }

        static void order2()
        {
            for (int i = 100; i > 0; i--)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write(i.ToString() + " ");
            }
        }`enter code here`
    }
}

0

আমি Task<T>পরিবর্তে ব্যবহার করার প্রস্তাব করছি Thread; এটি একাধিক পরামিতিগুলির অনুমতি দেয় এবং সত্যই জরিমানা চালায়।

এখানে একটি কার্যকারী উদাহরণ:

    public static void Main()
    {
        List<Task> tasks = new List<Task>();

        Console.WriteLine("Awaiting threads to finished...");

        string par1 = "foo";
        string par2 = "boo";
        int par3 = 3;

        for (int i = 0; i < 1000; i++)
        {
            tasks.Add(Task.Run(() => Calculate(par1, par2, par3))); 
        }

        Task.WaitAll(tasks.ToArray());

        Console.WriteLine("All threads finished!");
    }

    static bool Calculate1(string par1, string par2, int par3)
    {
        lock(_locker)
        {
            //...
            return true;
        }
    }

    // if need to lock, use this:
    private static Object _locker = new Object();"

    static bool Calculate2(string par1, string par2, int par3)
    {
        lock(_locker)
        {
            //...
            return true;
        }
    }

-2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace ConsoleApp6
{
    class Program
    {
        static void Main(string[] args)
        {

            int x = 10;
            Thread t1 =new Thread(new ParameterizedThreadStart(order1));
            t1.Start(x);

            Thread t2=new Thread(order2);
            t2.Priority = ThreadPriority.Highest;
            t2.Start();

            Console.ReadKey();
        }//Main

        static void  order1(object args)
        {
            int x = (int)args;


            for (int i = 0; i < x; i++)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.Write(i.ToString() + " ");
            }
        }

        static void order2()
        {
            for (int i = 100; i > 0; i--)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write(i.ToString() + " ");
            }
        }
    }
}

সি # থ্রেড সহ একাধিক থ্রেডিং আপনাকে ভাগ করা মেমরির মাধ্যমে সিঙ্ক্রোনাইজ করার জন্য আরও দক্ষ অ্যাপ্লিকেশন বিকাশ করতে দেয়।
মোহাম্মদ হাসেন ইসমাইল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.