どのようにしてC#のパラメータでスレッドを始めますか?
うん:
Thread t = new Thread (new ParameterizedThreadStart(myMethod));
t.Start (myParameterObject);
Threadコンストラクタの2つのオーバーロードのうちの1つは、単一のパラメータをstartメソッドに渡すことを可能にするParameterizedThreadStartデリゲートを受け取ります。残念ながらそれはただ一つのパラメータを許容し、それがオブジェクトとしてそれを渡すので安全でない方法でそうします。ラムダ式を使用して関連パラメータを取得し、厳密に型指定された方法で渡す方がはるかに簡単です。
以下を試してください
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) {
...
}
ラムダ式を使うことができます
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;
}
パラメータタイプはオブジェクトでなければなりません。
編集:
この答えは正しくありませんが、私はこのアプローチに対してはお勧めしません。ラムダ式を使用すると読みやすくなり、型キャストが不要になります。こちらを参照してください。 https://stackoverflow.com/a/1195915/52551
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();
ORあなたはdelegate
を使ってThreadStart
さえできます...
ThreadStart ts = delegate
{
bool moreWork = DoWork("param1", "param2", "param3");
if (moreWork)
{
DoMoreWork("param1", "param2");
}
};
new Thread(ts).Start();
ParameterizedThreadStart を使用してください。
ParametrizedThreadStart
を使用してください。
渡されたパラメータに問題がありました。 forループから整数を関数に渡して表示しましたが、常に異なる結果が出ました。 ParametrizedThreadStartと(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
は1つのパラメータを取ります。これを使用して、1つのパラメータ、または複数のプロパティを含むカスタムクラスを送信できます。
もう1つの方法は、インスタンスメンバーとして起動するメソッドを、設定するパラメータのプロパティと共にクラスに配置することです。クラスのインスタンスを作成し、プロパティを設定し、インスタンスとメソッドを指定してスレッドを起動すると、メソッドはプロパティにアクセスできます。
あなたは ParametrizedThreadStart デリゲートを使うことができます:
string parameter = "Hello world!";
Thread t = new Thread(new ParameterizedThreadStart(MyMethod));
t.Start(parameter);
BackgroundWorkerRunWorkerAsync メソッドを使用して値を渡すことができます。
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`
}
}
ここでさまざまな回答ですでに言及されているように、 Thread
クラスは現在(4.7.2)いくつかの constructors と 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
メソッドにanythingを渡すことができます。
ただし、このアプローチには1つの大きな問題があります。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}");
}
キャスティングは、通常はしたくないことです。
文字列以外の何かを誰かが渡すとどうなりますか?これは最初は不可能だと思われるため(が私のメソッドであるため、私は何をするかを知っていますまたはこのメソッドはプライベートです。それに何かを渡すには?)場合によっては問題にならないこともあれば、問題になることもあります。このような場合、おそらく InvalidCastException
になりますが、これはおそらくスレッドを終了するだけなので、おそらく気付かないでしょう。
解決策として、ParameterizedThreadStart<T>
のような汎用ParameterizedThreadStart
デリゲートを取得します。ここで、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();
したがって、この方法では、単にキャストすることを避け、スレッドにデータを提供するタイプセーフな方法があります;-)