2016-05-03 24 views
2

Task.Runを使用しようとすると、多くのコードが正常に読み込まれません。私はachiveたい何Task.Runを使用してFire&Forgetメソッドが動作しない

  • ASP.NETのWebフォームのイベント(イベントハンドラをクリックしてください)&メソッドを忘れて火を呼び出す(実行の電流の流れを遮断していません)。
    最初のバージョン:

    protected void btn_Click(object sender, EventArgs e) 
    { 
        // Some actions 
        // Should insert a record in database --> OK 
    
        //Tried this call with and without ConfigureAwait(false) 
        Task.Run(() => MyClass.doWork()).ConfigureAwait(false); 
    
        // Should insert a record in database --> OK 
        // Some actions not blocked by the previous call 
    } 
    
    public static class MyClass 
    { 
        public static void doWork() 
        { 
         // Should insert a record in database --> NOT INSERTED 
        } 
    } 
    


    番目のバージョン:私が試したし、それが働いていない理由をunderstantません何

protected void btn_Click(object sender, EventArgs e) 
{ 
    // Some actions 
    // Should insert a record in database --> OK 

    Bridge.call_doWork(); 

    // Should insert a record in database --> OK 
    // Some actions not blocked by the previous call 
} 

public static class Bridge 
{ 
    public static async Task call_doWork() 
    { 
     //Tried this call with and without ConfigureAwait(false) 
     await Task.Run(() => MyClass.doWork()).ConfigureAwait(false); 
    } 
} 

public static class MyClass 
{ 
    public static void doWork() 
    { 
     // Should insert a record in database --> NOT INSERTED 
    } 
} 

は、だから私は火を呼ぶ&メソッドを忘れるとレコードがデータベースに挿入されますが、レコードは挿入されません。

火の呼び出しの前後の挿入&忘れたメソッドが実行されます。

私の問題を解決する方法がわかりません。

+0

doWork()にブレークポイントを置くと、ブレークポイントにヒットしますか? –

+0

'MyClass.doWork()'が同期して動作することを確認しましたか? – weston

+0

申し訳ありませんが、サーバー上のコードをテストし、web.configでassemblyBindingを使用するため、デバッガを使用できません。 – krlzlx

答えて

2

HttpContextは、メインスレッド以外のスレッドでは使用できないため、依存することはできません。

ただし、タスクを開始するときにHttpContextのデータをメソッドに渡すことができます。たとえば:

Task.Run(() => MyClass.doWork(HttpContext.Current.Session["somedata"])).ConfigureAwait(false); 
+0

リクエストコンテキストは「利用できません」だけでなく、単にOPが達成しようとしていた過去のリクエストが完了していないというメモを追加することもできます。 –

+0

それはトリックを行うことができますが、doWorkメソッドのシグネチャやコードを変更することはできません。 – krlzlx

+0

@krlzlxそれでは、あなたはそれを同期して実行していると思います。 –

1

は私がいるHttpContext呼び出しでEventViewerイベントを取得していないのはなぜ?私はTask.Runの代わりにHostingEnvironment.QueueBackgroundWorkItemを使用するときに取得します。

OK、最初のオフ、あなたが利用可能QueueBackgroundWorkItem、なぜあなたはファイア・アンド・フォーゲット作業用これまで使用Task.Run希望を持っている場合は?

私のブログで説明しているように、using Task.Run for fire-and-forget on ASP.NET is a really bad ideaQueueBackgroundWorkItemは、の最小の実行可能なソリューションです。これは、信頼性が低い場合にのみ適用されます。

QueueBackgroundWorkItemTask.Runを超えて、あなたのために物事のカップルを行います。それは、(最小化しますが、作業が完了していないという可能性を排除しない)ASP.NETランタイムでの作業を登録し、それが例外をキャッチし、それらをログに記録しますあなた(なぜあなたはイベント通知を見ていたのですか)。

QBWIがあなたのために行っていたので、例外のイベントが表示されました。 Task.Runコードの場合、例外はキャッチされ、返されたTaskに置かれます(そして、そうする必要があります)。その場合、コードはそのタスクを完全に無視して、例外を黙って飲み込みます。

はい!私はHttpContextを使ってセッションを取得します。しかし、私は多くのコードを変更することなくそれを変更することはできません。

他にも述べたように、HttpContextはリクエストコンテキスト内でのみ有効です。したがって、明示的にバックグラウンドコードを実行すると、もちろん要求コンテキストはありません。バックグラウンドコードは、定義によって要求から独立していなければなりません。


しかし、私はあなたが一望できていると思う一つの他の本当に重要配慮があります:

public static void doWork() 
{ 
    // Should insert a record in database --> NOT INSERTED 
} 

はしばらくの間で一度doWorkが実行されない場合は、あなたのアプリが完全にOKであることを確認していますが、 ?そのため、バックグラウンドタスクには何が起こるのでしょうか。 ASP.NETは、バックグラウンドタスクを実行するのではなく、要求に応答するように設計されています。

青い月に1度は、doWorkによって挿入されたはずのレコードは表示されません。これが受け入れがたい場合は、火を忘れてはいけません。

+0

あなたの説明に感謝します。私は最終的に同期実装を使用しました。 – krlzlx

関連する問題