4

非同期で呼び出したいメソッドがあります。

void Foo()
{
}

実際、次の方法でこれを非同期的に呼び出すことができます。

delegate void DVoidMethod();
DVoidMethod FooDelegate = new DVoidMethod(Foo);
FooDelegate.BeginInvoke(null,null);

誰かが代替手段を持っていますか?

3行のコードは多すぎると思いますか?

4

6 に答える 6

10

免責事項:

これを実際のコードで使用しないでください。これは、OP が言及したコードを短縮するための単なる試みです。結果を返さずに実際の非同期呼び出しを行うには、次を使用します。

ThreadPool.QueueUserWorkItem(stateObject => Foo());

フレームワークでの使用ActionFuncデリゲート:

new Action(Foo).BeginInvoke(null, null);

Action<T>2.0から存在しています。他のバリアントは 3.5 で追加されます。ただし、2.0 では、さらに使用するために手動でそれらの束を宣言することができます。またはさらに良いことに、LINQBridgeを使用します。

于 2009-07-08T15:51:47.387 に答える
8

どうですか:

ThreadPool.QueueUserWorkItem(new WaitCallback((o) => Foo()));

新しいバージョンの .net で利用可能な TPL API を考慮して更新します。

.Net 4 以降では、次のことができます。

Task.Factory.StartNew(() => Foo());

.Net 4.5 以降では、次のこともできます。

Task.Run(() => Foo());

Task.Factory.StartNewTask.Runの違いは、「StartNew」メソッドには、状態、タスク作成オプション、必要に応じて追加の制御を提供するスケジューラを渡すことができるいくつかの追加パラメーターがあることです。

于 2009-07-08T15:54:20.530 に答える
3

Action と Func を使用せずに、void () デリゲートの場合は MethodInvoker を使用できます。

new MethodInvoker(Foo).BeginInvoke(null, null);

また、BeginInvoke メソッドを使用する場合は、デリゲートの実行が完了したときに EndInvoke を呼び出す必要があることに注意してください。そのため、上記の行は、コールバックを使用するように変更するか、デリゲートへの参照を保持する必要があります。 。 そのようです:

MethodInvoker mi = null;
IAsyncResult ar = null;

ar = (mi = new MethodInvoker(Foo)).BeginInvoke(null,null);


.. sometime later after the delegate has completed executing
mi.EndInvoke(ar);

これは、BeginInvoke を使用するときはいつでも当てはまります。したがって、BeginInvoke メソッドの使用はお勧めしません。

ThreadPoolを使用した@Stevenのソリューションは、私の意見でははるかに優れたソリューションです..そして彼は明らかに:)

于 2009-07-08T15:59:46.730 に答える
3

次の単純なコマンドを使用して、2 行 (.Net 1.1以前の場合)にまとめることができます。

delegate void DVoidMethod();
new FooDelegate(DVoidMethod).BeginInvoke(null, null)

しかし、2.0 以降のバージョンでは、Mehrdad の構文が機能します。

MSDN の 2.0 以降のアクション デリゲートを参照してください。

http://msdn.microsoft.com/en-us/library/018hxwa8(VS.80).aspx

于 2009-07-08T15:54:08.533 に答える
1

厳密に言えば、呼び出している関数の背後に実際のコードがどれだけあるかわからないため、パフォーマンスの観点からコードの行数について心配する必要はありません。

于 2009-07-08T17:14:26.517 に答える
1

古いスレッドですが、積み上げずにはいられませんでした。

結果を使用していない場合やメソッドの完了に反応していない場合でも、実際にはリークを避けるために EndInvoke を呼び出す必要があります。しかし、それは醜いものでなければならないという意味ではありません。

BeginInvoke は、コールバック パラメータとして AsyncCallback を想定しています。AsyncCallback のシグネチャは、IAsyncResult を受け取る void です。EndInvoke にはその署名があるため、次のようになります。

    //waste some time...
    void Foo() {}
    void InvokeFoo()
    {
        Action fooer = () => Foo();
        fooer.BeginInvoke(fooer.EndInvoke, null);            
    }
    void InvokeFoo2()
    {
        // or, less concise but some consider more readable:
        Action fooer = new Action(Foo); //...invoke doesn't change
    }
于 2010-02-10T16:58:06.043 に答える