2011-08-09 12 views
9

特定のデリゲートが実行できるスレッドを抽象化する方法はありますか?最初は呼び出し元のスレッドで実行できるようになりますが、特定の時間よりも長い時間がかかると実行をバックグラウンドスレッドに移動できます?デリゲートの実行をあるスレッドから別のスレッドに移すことは可能ですか?

デリゲートが非同期であると仮定します。私は、同期ブロックを取ってバックグラウンドスレッドに移動して並列性を高めようとはしていませんが、単純な操作のためにスレッドのオーバーヘッドを避けることによって非同期実行のパフォーマンスを向上させたいと考えています。私は等の明確なスタックの境界を確立することができれば、デリゲートまたはラムダの実行を一時停止することができますどのような方法があるかどう

は基本的に私は思ったんだけど、別のスレッドに移動し、再開

私はこれが可能である疑い、私はちょうど興味がある。

答えて

3

これは可能ですが、正しくするのは扱いにくく困難です。これを実現させる最善の方法は、coroutinesを使用することです。現在、コルーチンのパラダイムに適合する.NETの唯一のメカニズムは、yield returnキーワードによるC#のイテレータです。 は、あるスレッドから別のスレッドへのメソッドの実行を可能にする、理論上の何かを一緒にハックするです。しかし、これはブログにふさわしいハッキングに過ぎませんが、可能だと思います。

次善策は、Async CTPにアップグレードすることです。これはC#で利用できる機能であり、あなたが求めていることを正確に行うことができます。これは、提案されたawaitキーワードとそれに含まれるいくつかの巧妙な脆弱性でエレガントに達成されます。最終結果は、以下のようになります。

public async void SomeMethod() 
{ 
    // Do stuff on the calling thread. 

    await ThreadPool.SwitchTo(); // Switch to the ThreadPool. 

    // Do stuff on a ThreadPool thread now! 

    await MyForm.Dispatcher.SwitchTo(); // Switch to the UI thread. 

    // Do stuff on the UI thread now! 
} 

これはちょうどあなたが新しいawaitキーワードで行うことができ、多くの邪悪なクールなトリックの一つです。


対象は、特に作業項目の形で注入を受け入れるように設計されている場合は、実際には既存のスレッド上のコードの実行を注入することができる唯一の方法です。

あなたはイテレータでawaitキーワードを模倣する1つのそのような試みのために私の答えhereを見ることができます。 MindTouch Dreamフレームワークは、おそらくより良いバリエーションです。ポイントは、いくつかの巧妙なハッキングでスレッドの切り替えを引き起こすことが可能でなければならないということです。

+0

魅力的!私は間違いなく 'await'とAsync CTPに関するさらなる研究をしなければなりません。私はかなり待っているとは思っていませんでした。 – devios1

+0

うわー。それは滑らかです。 –

2

簡単にはありません。

デリゲートをステートマシンとして構成すると、ステート間の実行時間を追跡できます。希望のスレッショルドに達すると、新しいスレッドで次のステートを起動します。

より簡単な解決策は、新しいスレッドで起動することです。容認できない理由は何ですか?

(自分の携帯電話からの投稿 - 必要であれば、私は実際のキーボードでだとき、私はいくつかの擬似コードを提供します)

+0

まあ、それは私が考えなかった興味深い考えです。私の目的のために、私は代理人のフォーマットをかなりシンプルに保つことにもっと興味を持っています(ステートマシンは過剰です)。私はおそらくスレッドプールスレッドを使用するルートに行きます。簡単な操作のためにそれを最適化する方法があるのであれば、私はちょっと不思議でした。 – devios1

+0

ええ、ちょうどループの中で同じ操作をしているだけで、FSMは過剰です。しかし、その場合は、推定されたワークロード/反復に基づいて必要な実行時間を見積もり、使用するスレッドについて決定を下すことができます。 –

+0

そうですね、過去の実行時間のデータベースを保持し、その平均値を使ってバックグラウンドスレッドで実行するかどうかについて情報に基づいた判断を下すかもしれません。もちろん、すべてのメトリックを実行することは、現在のスレッドで実行することによって得られる最適化よりも時間がかかります(実際にはほとんど保証されています)。だから本当にそれは疑問点になります。しかし、考えてまだ興味深い。 – devios1

1

ありません、私はそれが可能だとは思いません。少なくとも正規の代議員と直接は関係がありません。ちょっとした作業の後に何らかの種類のIEnumerableを作成した場合は、手作業でいくつかの反復を実行してから、多くの反復の後にバックグラウンドスレッドで実行することができます。

ThreadPoolとTPLのタスクは十分なパフォーマンスが必要です。単にバックグラウンドスレッドで実行するだけです。タスクを使用するとオーバーヘッドが発生するという特定のベンチマークがない限り、早すぎて最適化しようとしているように見えます。

+0

実際、あなたは時期尚早な最適化について正しいと思います。私はそれをよく知っています(私は早すぎる最適化問題があることを認めます)。それで、なぜ私が言ったように、将来の潜在的な改善のための好奇心から、それをあまりにも真剣に受け止めていないのですか? ;) – devios1

関連する問題