1

Joseph Albahari による「Threading in C#」の「PART 1: GETTING STARTED」の Passing Data to a Threadに従います。

すなわちパッセージ:

====== 引用の開始

"このアプローチでは、メソッドに任意の数の引数を (どこに?) 渡すことができます。複数ステートメントのラムダで実装全体をラップすることもできます。

new Thread (() =>  
{  
  Console.WriteLine ("I'm running on another thread!");  
  Console.WriteLine ("This is so easy!");  
}).Start();*  

匿名メソッドを使用して、C# 2.0 で同じことをほぼ同じように簡単に行うことができます。

  new Thread (delegate()  
  {  
  ...
  }).Start();

============ 引用の終わり

つまり、次のように「簡単に」試しました。

new Thread
(delegate
  {
    Console.WriteLine("I'm running on another thread!");
    Console.WriteLine("This is so easy!");
   }
).Start();

しかし、それはエラーを生成します:

次のメソッドまたはプロパティ間の呼び出しがあいまいです: 'System.Threading.Thread.Thread(System.Threading.ThreadStart)' と 'System.Threading.Thread.Thread(System.Threading.ParameterizedThreadStart)'

  1. コードを実行するためにコードをどのように明確化できますか? 回答済み (かっこを忘れていました。とにかく、それは元の主な質問ではありませんでした)
  2. () =>また、空のリストがどこに向けられている/適用されている のかよくわかりませんでし たか?
  3. また、「メソッドに任意の数の引数を渡すことができる」メソッドとは何ですか?
  4. 空のリストを介した (任意の数の) 引数の受け渡しを理解する方法は?

更新(Jon Skeet のコメントに対応):
いいえ、C# 2 にこだわっていません。

前の文章と同じ質問:

========== 引用の開始:
"スレッドのターゲット メソッドに引数を渡す最も簡単な方法は、目的の引数でメソッドを呼び出すラムダ式を実行することです。

static void Main()
{
  Thread t = new Thread ( () => Print ("Hello from t!") );
  t.Start();
}

static void Print (string message) 
{
  Console.WriteLine (message);
}

このアプローチでは、任意の数の引数をメソッドに渡すことができます。」

=============== 引用の終わり

Update2:
最も完全な答えは@LeeによるIMOですが、最初に尋ねたことさえなかったことにすぐに答えることを推測するための正しい別の答えとしてマークしました-空の括弧に何かを入れる方法(リストで呼び出すのはすでに怖いです)または引数による)

4

4 に答える 4

3

引数リストを明示的にする必要があります:

new Thread
(delegate()
  {
    Console.WriteLine("I'm running on another thread!");
    Console.WriteLine("This is so easy!");
   }
).Start();

このdelegateキーワードを使用すると、匿名メソッドを定義できます。ラムダ式 (つまり、() => { ... }構文を使用) は似ていますが、使用delegateするとパラメーター リストを省略できます。この場合、Thread異なるデリゲート型を取る 2 つのコンストラクターがあるため、これはあいまいです。次のThreadStartように定義される

delegate void ThreadStart();

もう 1 つは、次のParameterizedThreadStartように定義される a を取ります。

delegate void ParameterizedThreadStart(object state);

パラメータ リストを省略しているため、コンパイラは使用しているデリゲート タイプを認識できません。

「任意の数の引数」は、デリゲートによって閉じられる変数であると想定しています。たとえば、次のようにすることができます。

string message = "This is so easy!";
var thread = new Thread(delegate() {
    Console.WriteLine(message);
});
thread.Start();

a を使用しParameterizedThreadStartて、任意のオブジェクトをスレッド デリゲートに渡すことができます。

public class ThreadData {
   //properties to pass to thread
}

ThreadData data = new ThreadData { ... }
Thread thread = new Thread((object state) => {
    ThreadData data = (ThreadData)state;
});

thread.Start(data);
于 2013-02-22T12:47:33.697 に答える
2

パラメータを指定するには、後に括弧が必要ですdelegate。この場合はパラメータはありません。

new Thread(
  delegate() {
    Console.WriteLine("I'm running on another thread!");
    Console.WriteLine("This is so easy!");
  }
).Start();

著者が話している「任意の数の引数」とは、データをStartメソッドに渡すことなく、別のスレッドで実行されるコード内でデリゲートが作成されるスコープからデータを使用できることです。

string msg1 = "I'm running on another thread!";
string msg2 = "This is so easy!";
new Thread(
  delegate() {
    Console.WriteLine(msg1);
    Console.WriteLine(msg2);
  }
).Start();

実際に起こっていることは、変数がメソッド内のローカル変数ではなくなり、代わりに、デリゲートが定義されているメソッドと共有するクロージャーに自動的に格納されることです。

スレッドを 1 つだけ開始したい場合、これはうまく機能します。異なるデータを使用する複数のスレッドを開始する場合は、データをStartメソッドに渡すか、データを保持できるクラスを作成し、スレッドのコードをクラスに配置して、スレッドごとに 1 つのインスタンスを作成します。始める。

于 2013-02-22T12:56:00.603 に答える
1

あいまいな呼び出しを解決するために、空の括弧を追加できます (デリゲートは ThreadStart デリゲートとして扱われます)。

new Thread(delegate() {
    Console.WriteLine("I'm running on another thread!");
    Console.WriteLine("This is so easy!");
}).Start();

または、状態パラメーターを追加します (デリゲートは ParametrizedThreadStart として扱われます) 動作しますが、そのパラメーターは必要ないため、奇妙です。

new Thread(delegate(object state) {
    Console.WriteLine("I'm running on another thread!");
    Console.WriteLine("This is so easy!");
}).Start();

またはデリゲートをキャストThreadStart

new Thread((ThreadStart)delegate {
    Console.WriteLine("I'm running on another thread!");
    Console.WriteLine("This is so easy!");
}).Start();
于 2013-02-22T12:46:45.747 に答える
1

() =>C# では空のリストではありません。本で使用されているコンテキストでは、ラムダ式の開始です。は()、この式が引数を取らないことを意味します。

于 2013-02-22T12:50:51.557 に答える