আপনি কীভাবে সি # তে পরামিতি দিয়ে একটি থ্রেড শুরু করবেন?
আপনি কীভাবে সি # তে পরামিতি দিয়ে একটি থ্রেড শুরু করবেন?
উত্তর:
হ্যাঁ:
Thread t = new Thread (new ParameterizedThreadStart(myMethod));
t.Start (myParameterObject);
void MyParamObject(object myUrl){ //do stuff }
প্যারামিটারের ধরণ থাকতে হবেobject
ParameterizedThreadStart
প্রশ্নটি পাঠ্য থেকে ওপি কীভাবে ব্যবহার করতে এবং স্পষ্টভাবে জানে , সম্ভবত এটি নয়।
থ্রেড কনস্ট্রাক্টরের 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) {
...
}
Dim thr As New Thread(Sub() DoStuff(settings))
আপনি ল্যাম্বদা এক্সপ্রেশন ব্যবহার করতে পারেন
private void MyMethod(string param1,int param2)
{
//do stuff
}
Thread myNewThread = new Thread(() => MyMethod("param1",5));
myNewThread.Start();
এটি এখন পর্যন্ত সবচেয়ে ভাল উত্তর আমি খুঁজে পেতে পারি, এটি দ্রুত এবং সহজ।
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
?
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"
}
}
লম্বদা ব্যবহারের মতো সহজ উপায় ..
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..
}
ব্যবহার ParametrizedThreadStart
।
ইতিমধ্যে এখানে বিভিন্ন 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ালাই এড়ানো এবং কোনও থ্রেডে ডেটা সরবরাহ করার একটি টাইপসেজ উপায় আছে ;-)
private static void MyMethod<T>(T myData) { T message = myData; Console.WriteLine($"the thread wrote: {message}"); }
message.Length
সম্ভব নয় ইত্যাদি)
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 )
উত্তীর্ণ প্যারামিটারে আমার সমস্যা ছিল। আমি একটি লুপ থেকে ফাংশনটিতে পূর্ণসংখ্যার পাস করেছি এবং এটি প্রদর্শন করেছি, তবে এটি সর্বদা ভিন্ন ফলাফল দেয়। যেমন (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;
}
ParameterizedThreadStart
এক পরামিতি গ্রহণ করে। আপনি এটি ব্যবহার করতে পারেন একটি প্যারামিটার পাঠাতে, বা একটি কাস্টম ক্লাস যা বেশ কয়েকটি বৈশিষ্ট্যযুক্ত।
আরেকটি পদ্ধতি হ'ল আপনি যে প্যারামিটারগুলি সেট করতে চান তার বৈশিষ্ট্য সহ ক্লাসে উদাহরণস্বরূপ সদস্য হিসাবে যে পদ্ধতিটি শুরু করতে চান তা স্থাপন করা। শ্রেণীর একটি উদাহরণ তৈরি করুন, বৈশিষ্ট্যগুলি সেট করুন এবং উদাহরণ এবং পদ্ধতিটি উল্লেখ করে থ্রেড শুরু করুন এবং পদ্ধতিটি বৈশিষ্ট্যগুলিতে অ্যাক্সেস করতে পারে।
আপনি প্যারামাইট্রিজড ট্রেড স্টার্ট প্রতিনিধি ব্যবহার করতে পারেন :
string parameter = "Hello world!";
Thread t = new Thread(new ParameterizedThreadStart(MyMethod));
t.Start(parameter);
আপনি ব্যাকগ্রাউন্ড ওয়ার্কার রান ওয়ার্কারএন্সিঙ্ক পদ্ধতিটি ব্যবহার করতে পারেন এবং আপনার মানটি পাস করতে পারেন ।
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`
}
}
আমি 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;
}
}
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() + " ");
}
}
}
}