2011-07-25 13 views
0

背景:フォームロード中にストアドプロシージャを呼び出すことがありました。しかし、この結果、UIには次善の結果が得られたため、SPコールはShownイベントの中で独自のタスクに入れました。これは通常、フォーム表示プロセスの最後のイベントであるため、フォームのロードイベントに物を入れるよりもはるかに良い結果になりました。私が持っている:非GUIスレッドでタスク完了通知を取得する方法

private void MainForm_Shown(object sender, EventArgs e) 
{ 
    dbCheckTask = Task<bool>.Factory.StartNew(RunSPAndCheckStuff()); 

    // both of below run on the GUI thread. 

    // if I print the thread ID in mycallback it is the GUI thread id 
    dbCheckTask.ContinueWith(mycallback()); 

    // I also tried below. But obviously, that too runs on the GUI thread 
    mycallback(dbCheckTask.Result) 

} 

彼らはGUIスレッドで火災ので、私のスタートアップフォームの塗料はまだ瞬間もスムーズでもありません。イベントに頼らずに、GUI以外のスレッドでコールバックを完了させるにはどうすればよいですか?タスクが完了し、何かが間違っていて何かが間違っている(bool結果がfalseを返す)場合にのみ、ユーザーはメッセージボックスポップを取得します。それまでは、彼は先に進んで、データベースに関連しない他のものをフォーム上で行うことができました。私はどのように非GUIスレッドでタスクの結果とタスク補完のコールバックを得ることができます助言してください。ありがとう

+0

それはすでに動作するはずのようにこれは私には見えます - あなたはmycallback()メソッドのコードまたは擬似コードを投稿することができますか? – Stuart

+0

私はあなたが同期コンテキストにバインドされていないスケジューラを得るためにTaskScheduler.Defaultを使うことができると信じています。この問題がまったく見つかっていないという事実は、TaskScheduler.Currentがある時点でsycnchronizedタスクスケジューラに設定されていることを示しています。 –

+0

@Stuart。この質問に対する他の人の提案がうまくいかない場合は、サンプルコードを投稿します。thx – Gullu

答えて

1

私はBackgroundWorkerを個人的に使用します。タスクスレッドで実行するコールバックを取得するための一つの方法は、次のようにメソッドコールとタスクの作成を修正するために、次のようになります。

private void MainForm_Shown(object sender, EventArgs e) 
{ 
    dbCheckTask = Task<bool>.Factory.StartNew(() => RunSPAndCheckStuff(mycallback)); 
    ... 
} 

private bool RunSPAndCheckStuff(Action<bool> callback) 
{ 
    bool result = false; 
    // Do stuff 
    callback(result); 
    return result; 
} 
+0

これはうまくいくと思います。試して投稿を返信する – Gullu

+0

thx Sir。作品。 – Gullu

+0

これは動作しますが、バックグラウンドスレッドはSPが戻るのを待ってブロックされます。どんな種類のI/Oを扱う場合でも、適切な非同期APIを使用する必要があります。 – BFree

1
あなたが使用してになります

非同期APIのではなく、バックグラウンドスレッドでの同期バージョンを呼び出すより:

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.beginexecutenonquery.aspx

と利点は、スレッドがブロックされないことである、と私は信じていますコールバックはThreadPoolスレッドで呼び出されます。 GUIスレッドではありません。そこから、Invoke/BeginInvokeを使ってGUI呼び出しをGUIスレッドにマーシャリングすることができます。

+0

このようにするつもりはありません。いいヒント。私はこれを行うにはトプルな方法があると確信しています。 thx – Gullu

+0

はい、これはFromAsyncメソッドを使って簡単に行うことができます:http://msdn.microsoft.com/en-us/library/dd321311.aspx – BFree

0

はなぜやっていない:

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

とWorkerMethodを(定義)のとおりです。

void WorkerMethod() 
{ 
    RunSPAndCheckStuff(); // this blocks until finished 
    DoSomeMoreStuff(); // then this continuous 
} 

それ以外の場合は、達成したいことの詳細をご記入ください。

3

これらすべてのものは、hereをダウンロードできるAsync言語拡張で最もよく扱われ、ホームページはhereです。

asyncawaitというキーワードをC#とVBに導入しました。これにより、1つの方法でも簡単にUIとバックグラウンドスレッド間を行き来するコードを書くことができます。コンパイラはそれをタスク、継続、エラーキャッチなどに変換するでしょう。あなたはそれを心配する必要はありません。あなたはこの1つだろう興味う例:

public async void AsyncSwitchToCPU() { 
    Console.WriteLine("On the UI thread."); 

    // Switch to a thread pool thread: 
    await new SynchronizationContext().SwitchTo(); 

    Console.WriteLine("Starting CPU-intensive work on background thread..."); 
    int result = DoCpuIntensiveWork(); 
    Console.WriteLine("Done with CPU-intensive work!"); 

    // Switch back to UI thread 
    await Application.Current.Dispatcher.SwitchTo();     

    Console.WriteLine("Back on the UI thread. Result is {0}.", result); 
} 

public int DoCpuIntensiveWork() 
{ 
    // Simulate some CPU-bound work on the background thread: 
    Thread.Sleep(5000); 
    return 123; 
} 

これさえ(MSからいくつかの予約付き)ゴーライブライセンスを持っています。 F#から借りた非常にエレガントなもの。

RGDSゲルト・ヤン

+0

うわー。素敵なもの。しかし、私の簡単な必要性のために少し過剰です。私はこれを読み上げます。ありがとう – Gullu