質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

1467閲覧

ASP.NET WebAPIで時々15秒程度レスポンスが返ってこない

spweek2022

総合スコア2

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2022/11/21 08:18

編集2022/12/12 07:57

前提

WindowsServer2016 Standard
VisualStudio2015Pro(C#)

実現したいこと

ASP.NETでWebAPIを作成しております。

発生している問題・エラーメッセージ

レスポンスが不定期で15秒程度かかることがあります。通常時は1秒以内です。
原因を知りたいです。

いくつかAPI関数がありますが、15秒かかるのは1つ関数のみです。
処理自体は1秒以内で終了することは確認済みです。

クライアント側はブラウザやC#のHttpClientの両方で発生します。
Fidderで見るとサーバからレスポンスが15秒かえってきていません。

該当のソースコード

C#

1public class WorkResultController : ApiController 2{ 3 public object GetWorkResultsByDate(string div, string datefrom, string dateto) 4 { 5 try 6 { 7 var sw = new System.Diagnostics.Stopwatch(); 8 sw.Start(); 9 string connectionString = AccessConnection.GetConnection(div); 10 using (OleDbConnection cn = new OleDbConnection(connectionString)) 11 { 12 cn.Open(); 13 string sql = "SELECT * FROM testテーブル WHERE 日付 >= ? AND 日付 <= ?"; 14 OleDbCommand cmd = new OleDbCommand(sql, cn); 15 cmd.Parameters.Add("@開始", OleDbType.Date).Value = datefrom; 16 cmd.Parameters.Add("@終了", OleDbType.Date).Value = dateto; 17 DataTable dt = new DataTable(); 18 OleDbDataAdapter ada = new OleDbDataAdapter(cmd); 19 ada.Fill(dt); 20 var rtn = Newtonsoft.Json.JsonConvert.DeserializeObject(Newtonsoft.Json.JsonConvert.SerializeObject(dt)); 21 sw.Stop(); 22 //$"{sw.Elapsed.TotalSeconds}秒"); 23      // 1秒以内で終了していることを確認済 24 return rtn; 25 } 26 } 27 catch (Exception ex) 28 { 29 //err.ErrorMessage = ex.Message; 30 return 31 } 32 } 33 34}

試したこと

IISのアプリケーションプールは、下記サイトを参考に開始モードをAlwaysRunning、
アイドル状態のタイムアウトを1440、
有効化されたプリロードをTrueに設定しました。

https://thwack.solarwinds.com/resources/japan/f/forum/973/orion-web

補足情報(FW/ツールのバージョンなど)

[追記]
関数内でAccessのデーベースにアクセスしています。
データベースは別サーバの共有フォルダにあります。

2022/12/12 追記

下記コードのreturn response;の1行が、時々非常に遅い(15秒)ことがあることがわかりました。

C#

1 public HttpResponseMessage GetWorkResultsByDate(string div, string datefrom, string dateto) 2 { 3 var sw = new System.Diagnostics.Stopwatch(); 4 sw.Start(); 5 6 try 7 { 8 DBType dbtype = DBType.Access; 9 string connectionString = DBConnectionString.GetConnection(div, ref dbtype); 10 using (OleDbConnection cn = new OleDbConnection(connectionString)) 11 { 12 cn.Open(); 13 string sql = "SELECT * FROM testテーブル WHERE 日付 >= ? AND 日付 <= ?"; 14 OleDbCommand cmd = new OleDbCommand(sql, cn); 15 cmd.Parameters.Add("@開始", OleDbType.Date).Value = datefrom; 16 cmd.Parameters.Add("@終了", OleDbType.Date).Value = dateto; 17 DataTable dt = new DataTable(); 18 OleDbDataAdapter ada = new OleDbDataAdapter(cmd); 19 ada.Fill(dt); 20 21 //↓速度改善試行 22 IEnumerable<WorkResult> rtnList = dt.AsEnumerable().Select(row => new WorkResult 23 { 24 xxxxx= Convert.ToInt32(row["ID"]), 25 26 }).ToList(); 27 //↑速度改善試行 28 29 sw.Stop(); 30 Logger.WriteLog(MethodBase.GetCurrentMethod().Name, $"{sw.Elapsed.TotalSeconds}秒"); 31 sw.Reset(); 32 sw.Start(); 33 34 //return Request.CreateResponse(HttpStatusCode.OK, rtnList); //速度改善試行 35 var response = Request.CreateResponse(HttpStatusCode.OK); 36 response.Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(rtnList, Newtonsoft.Json.Formatting.Indented), System.Text.Encoding.UTF8, "application/json"); 37 38 sw.Stop(); 39 Logger.WriteLog(MethodBase.GetCurrentMethod().Name, $"CheckPoint {sw.Elapsed.TotalSeconds}秒"); 40 sw.Reset(); 41 sw.Start(); 42 43 return response; 44 } 45 } 46 catch (Exception ex) 47 { 48 Logger.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message); 49 MyApiError err = new MyApiError(); 50 err.ErrorMessage = ex.Message; 51 return Request.CreateResponse(HttpStatusCode.OK, err); 52 } 53 finally 54 { 55 sw.Stop(); 56 Logger.WriteLog(MethodBase.GetCurrentMethod().Name, $"finally {sw.Elapsed.TotalSeconds}秒"); 57 } 58 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tom_MR_Riddle

2022/11/21 10:00

渡はJava専門なので役に立たないかもですが少し思うところがあります。 バッファなどが使われる関係でストリームに流し込んだデータがクライアントへの転送待機状態になっているかもしれません。 バッファが貯まるか一定時間経過するとサーバー側のデータが実際にクライアントに送信されます。 もう送信すべきデータが無いなど明示的にデータ送信を完了させたい場合は一般的に Flush と呼ばれる 転送待機データを実際にクライアントに流す操作が必要です。 https://stackoverflow.com/questions/29793308/asp-net-web-api-pushstreamcontent-flush-does-not-flush
退会済みユーザー

退会済みユーザー

2022/11/21 14:50

> レスポンスが不定期で15秒程度かかることがあります。 どのぐらいの頻度なのですか。 > いくつかAPI関数がありますが、15秒かかるのは1つ関数のみです。 それはどうやって確認しましたか。ログを取るとかして「1つ関数のみ」なのは絶対間違いないことは確認しましたか。 ログが取ってあればもっと原因を絞れると思うのですがそういうことはしてないのですか。
spweek2022

2022/11/21 23:51

ご回答ありがとうございます。 クライアント側でログを取っており、1つの関数以外は今のところ遅延は発生しておりません。 数十回リクエストしたうちに1回程度の頻度で発生しております。 不定期で時間が空いたり、間隔が詰まったりしており、発生条件がわかっておりません。
退会済みユーザー

退会済みユーザー

2022/11/22 01:26

> クライアント側でログを取っており、 クライアント側では何に時間がかかっているのか特定する情報を得るのは無理ではないのですか? サーバー側でログを取ることをお勧めします。IIS にログを取る機能があります。それに加えてsw.Elapsed.TotalSeconds もログに残すとかして。 今提供されている情報から Q&A を通じて原因特定のお手伝いをする気力が自分にはありません。お役に立てずすみませんが、他の回答者の出現をお待ちください。
guest

回答1

0

自己解決

AccessDBのクローズに時間がかかっていたようです。
ConnectionStringに「OLE DB Services=-1;」を追加することで、解消しました。

【参考】       
https://stackoverflow.com/questions/38212700/oledbconnection-close-and-or-dispose-are-very-slow-take-20s-to-execute

投稿2022/12/29 03:41

spweek2022

総合スコア2

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問