あなたの質問の主題によると、答えはこれらの太字になります。MSDNは良くないかもしれませんが、それでも良いです:)
Jeffrey Richter が、上記の質問であなたが尋ねたことについて書いています。彼は MSDN マガジンにこの記事を掲載しています。 http://msdn.microsoft.com/en-us/magazine/cc164139.aspx
この記事では、BeginInvoke と EndInvoke が .NET で実際にどのように実装されているか (実際にはそうではないかもしれませんが、非常に近い) の実装について説明します。 CLR。この記事に時間を投資してください。その後は、先を読む必要はないと思います。
Jeffrey richter も、彼の著書 CLR Via C# の中で、これについて非常によく説明しています。
ほとんどの UI アプリケーションはシングル スレッドです。UI 上のコントロールには、それらが作成されたスレッドを使用してのみアクセスできます。
これを達成するために Control.Invoke が Winforms に存在します。UI スレッドでコードを自動的に呼び出します。WPF の世界では、Control.Invoke はありません。WPF には、Control の代わりに Dispatcher があります。
今デリゲート対デリゲート。 Hans Passant は非常に素晴らしい回答を提供してくれました。
ですから、少し詳しく説明するために、この回答を書いています。
MSDN で言及されているデリゲートはクラスです。このコードを見てみましょう (msdn http://msdn.microsoft.com/en-us/library/ms173171(v=vs.80).aspxから取得)
public delegate int PerformCalculation(int x, int y);
ここでわかるように、デリゲートがあります (小さな 'd' が付いていることに注意してください)。これは、デリゲートを定義するためのキーワード、または簡単な言葉で言えば、メソッドへの参照を実際に含む変数 PerformCalculation を定義するためのキーワードです。
あなたはすでにこれを認識していると思いますが、完全を期すために。
この変数を使用して、次のようなコードを使用してメソッドを呼び出します。
using System;
// Declare delegate -- defines required signature:
delegate void SampleDelegate(string message);
class TestDelegate
{
private void CallMeUsingDelegate(string m_param)
{
Console.WriteLine("Called me using parameter - " + m_param);
}
public static void Main(string[] args)
{
// Here is the Code that uses the delegate defined above.
SampleDelegate sd = new SampleDelegate(CallMeUsingDelegate);
sd.Invoke("FromMain");
}
}
メソッドを呼び出すには、上記の CallMeUsingDelegate メソッドとして完全なメソッドを記述する必要があります。C# には、実際にメソッドとして記述することなくメソッドを呼び出すために使用できるこの匿名メソッドがあります。
したがって、上記のコードは次のようにも記述できます。
システムを使用する; // デリゲートを宣言 -- 必要な署名を定義: delegate void SampleDelegate(string message);
class TestDelegate
{
public static void Main(string[] args)
{
// Here is the Code that uses the delegate defined above.
SampleDelegate sd = delegate(param) {
Console.WriteLine("Called me using parameter - " + param);
};
sd.Invoke("FromMain");
}
}
これは上記のコードと同じ働きをします。しかし、今はもう少し少ないコードを書く必要があります。コンパイラは、上記の両方のバージョンに対して同一の IL コードを作成します。ただし、2 の場合、新しいメソッドにはコンパイラによって自動生成された名前が付けられます。
BeginInvoke と EndInvoke に関しては、メソッドを非同期的に呼び出すために使用されます。これは、CLR で利用可能なスレッドプールを使用して行われます。
基本的に何が起こるかは、次を使用してメソッドを呼び出すことです
IAsyncResult ar = sd.BeginInvoke(CallMeUsingDelegate, callMeOnCompletion, sd);
ここで Delegate は、呼び出しているメソッドです。プログラムの Thread が BeginInvoke メソッドを呼び出し、CLR ThreadPool スレッドの Delegate パラメータで指定されたメソッドを内部的に呼び出します。次に、プログラムを実行し続け、IAsyncResult インターフェイスを実装するオブジェクトを返します。このオブジェクトを使用して、デリゲートを使用して呼び出されたタスクの進行状況についてクエリを実行できます (3 パラメーターとして渡されたデリゲート sd に注意してください)。
CallMeUsingDelegate メソッドは別のスレッド ( ThreadPool ) で呼び出されます。タスクが完了すると、ThreadPool は 2 パラメーターとして指定された Callback メソッドを呼び出します。
このすべてを見て、なぜ EndInvoke が必要なのかと思うかもしれません。
EndInvoke を呼び出さないと、CLR ThreadPool がこの操作への参照を保持し、メモリ リークが発生するためです。そのため、指定された Callback メソッドで EndInvoke を呼び出すことを常にお勧めします。
これで(すべてではありませんが)解決したことを願っていますが、いくつかの考えがあります。