10

ASP.NET MVC4Webアプリケーションに取り組んでいます。私は.NET4.5を使用しており、新しい非同期APIを利用しようとしています。

すぐに重要な値をすぐに返す間に、非同期タスクを後で実行するようにスケジュールしたい状況がいくつかあります。たとえば、これは「ログイン」メソッドで、新しいSessionIDをできるだけ早く返したいのですが、SessionIDを返したら、期限切れの古いSessionIDを削除したいと思います。

public async Task<Guid> LogIn(string UserName, string Password)
{
    //Asynchronously get ClientID from DB using UserName and Password

    Session NewSession = new Session()
    {
        ClientID = ClientID,
        TimeStamp = DateTime.Now
    };
    DB.Sessions.Add(NewSession);
    await DB.SaveChangesAsync();    //NewSession.ID is autopopulated by DB

    CleanSessions(ClientID);    //Async method which I want to execute later

    return NewSession.ID;
}

private async void CleanSessions(int ClientID)
{
    //Asynchronously get expired sessions from DB based on ClientID and mark them for removal
    await DB.SaveChangesAsync();
}

Task.Run()とParallel.Invoke()の組み合わせなど、さまざまなことを試しましたが、CleanSessionsが呼び出されることはありません。バックグラウンドタスクのスケジューリングを実現するにはどうすればよいですか?

4

2 に答える 2

18

要求なしでASP.NETでタスクを実行することはお勧めしません。危ないです。

CleanSessionsそうは言っても、リターンに変更すると、Task次のように実行できます。

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

CleanSessionsあなたの場合は、実行しないか、実行の途中で終了しても(リサイクルのためにASP.NETで発生する可能性があります)、長期的な問題はないので、問題ないと思います。リクエストに関連付けられていない作業が進行中であることをASP.NETに通知する場合は、次のようBackgroundTaskManagerに私のブログのを使用できます。

BackgroundTaskManager.Run(() => CleanSessions());
于 2013-02-27T23:39:02.860 に答える
0

すでに述べたように、ASP.NET内で「ファイア・アンド・フォーゲット」を実行しようとしている場合は、;を確認することをお勧めしますConfigureAwait。これをの一部として使用してawait、sync-contextを無視するように指示できます。それをASP.NET実行パイプラインに結び付けるのは同期コンテキストですが、それが必要でない場合は回避できます。例えば:

public async Task<Guid> LogIn(string UserName, string Password)
{
    //Asynchronously get ClientID from DB using UserName and Password

    Session NewSession = new Session()
    {
        ClientID = ClientID,
        TimeStamp = DateTime.Now
    };
    DB.Sessions.Add(NewSession);
    await DB.SaveChangesAsync().ConfigureAwait(false);    //NewSession.ID is autopopulated by DB

    await CleanSessions(ClientID).ConfigureAwait(false);    //Async method which I want to execute later

    return NewSession.ID;
}
// simplified: no need for this to be full "async"
private Task CleanSessions(int ClientID)
{
    //Asynchronously get expired sessions from DB based on ClientID
    return DB.SaveChangesAsync();
}
于 2013-02-28T07:04:34.960 に答える