7

何かを見落としている可能性があることは承知していますが、私が開発したことも、普段は保守していないアプリケーションを修正しようとしているので、単純な間違いを犯している場合は、あらかじめご容赦ください。

現在、特定の機能を実行するときにタイムアウトを引き起こしているこの Web アプリに問題があります。私はそれを 1 つまで追跡しました。ストアド プロシージャを実行しており、ストアド プロシージャが影響を受ける行の数を返すことを期待しています。それはすべてうまくてダンディです。ただし、このストアド プロシージャは 50 秒以上実行され、タイムアウトを引き起こしています。また、これが発生している間、UI が 50 秒間ハングすることは望ましくありません。変更された情報に基づいてデータベース内のいくつかのステータス フィールドを更新しているだけであり、返されるものはエンド ユーザーには役に立たないため、ユーザーがアプリケーションを引き続き使用できるように、トリガーして忘れる必要があります。

タスクの作成とスレッドの作成の両方を試みましたが、何らかの理由で関数がこれが完了するのを待つことを主張しています。

これは、ストアド プロシージャを呼び出す関数です。

 public static void UpdateComputerStatusByApplicationID(int ApplicationID)
{
    using (SqlConnection Conn = new SqlConnection(GlobalMethods.CONNECTION_STRING))
    {
        SqlCommand Cmd = new SqlCommand("UpdateComputerStatusByApplicationId", Conn);
        Cmd.CommandType = CommandType.StoredProcedure;
        Cmd.Parameters.Add("@applicationid", SqlDbType.Int).Value = ApplicationID;

        Conn.Open();
        Cmd.ExecuteNonQuery();
        Conn.Close();
    }
}

そして、例外は Cmd.ExecuteNonQuery(); から来ています。これはタイムアウト例外です。

これは、関数からタスクとして呼び出している場所です。

public void UpdateApplication(a_Applications newApplication, XPToWin7 xpToWin7)
    {
        try
        {
            var orginalApplication = GetApplication(newApplication.AutoNumber);
            ObjectContext.ApplyCurrentValues(orginalApplication.EntityKey.EntitySetName, newApplication);

            if (xpToWin7 != null)
            {
                UnlinkXPAppWithWin7App(orginalApplication.AutoNumber);
                LinkXPAppWithWin7App(orginalApplication.AutoNumber, xpToWin7);
            }

            Task UpdateComputerStatus = Task.Factory.StartNew(() =>
            {
                DAL.UpdateComputerStatusByApplicationID(orginalApplication.AutoNumber);
            }, TaskCreationOptions.LongRunning);

            SaveChanges();
        }
        catch (Exception ex)
        {
            throw new Exception("Exception when updating the application" + ex.Message, ex);
        }
    }

どこが間違っているのか、なぜ意図したとおりに機能しないのかはわかりませんが、この関数が呼び出されると、cmd.ExecuteNonQuery(); からの内部例外がスローされるまで、UI でハングします。.

どんな助けや提案も大歓迎です!

4

1 に答える 1

8

ストアド プロシージャをクライアントから非同期に呼び出すのは大変な作業です。複数のスレッド、BeginXXX および EndXXX メソッドを検討し、コールバックを使用し、アプリケーションが完了するまでアクティブなままにしておく必要があります。そうしないと、ロールバックが発生する可能性があります。はい、可能です - この回答をのぞいてみてください: C# での SQL Server ストアド プロシージャの非同期呼び出し

もっと簡単な方法があるかもしれません - ストアド プロシージャを非同期にしてみませんか? Service Broker を使用すると、ストアド プロシージャをアクティブ化する単純なキューを作成できます。呼び出し元のストアド プロシージャは、応答を待つ必要はありません。リクエストの詳細を渡す新しい会話を作成するだけで、すぐに戻ります。アクティブ化されたストアド プロシージャは、数秒、数分、または数時間かかる可能性のあるすべての面倒な作業を行うものですが、応答を待っているわけではないため、UI にとってはそれほど重要ではありません。UI がシャットダウンしても、非同期ストアド プロシージャは完了するまで実行されます。

http://rusanu.com/2009/08/05/asynchronous-procedure-execution/

于 2013-05-22T17:16:32.360 に答える