トップ回答者
ボタンクリックを連続でおこなうとポストバックしなくなる

質問
-
環境
windows server 2012
iis 8.0.9200.16384
.net framework v4.0
windows7 profrssional SP1
ie 11.9600.17914
visual studio express 2012 for web(VB.NET)で作成
上記環境で、GridViewとボタンを同じUpdatePanel内に配置し、ボタンクリックによりサーバ側でデータベースからデータセットを
取得しGridViewにバインドしています。UpdatePanelのUpdateModeはAlwaysにしています。
このボタンを普通にクリックしている分には問題ないのですが、サーバ側のボタンクリック処理に300万カウント行うDo~Loop処理を
加えたうえで連続クリックしていると、ポストバックしなくなるような現象が発生し、IEを再起動しないと復旧しない状態になってしまいます。
wiresharkで見たところ、現象が発生しているときはクリック毎にIE側からIISへの接続が切断されていました。
(RSTフラグのデータが発行されている)
2重クリック防止の処置などがあるのは知っているのですが、上記のような現象がなぜ起こるのかご存知の方がいましたら
ご教示頂ければ幸いです。
以上、宜しくお願い致します。
回答
-
最初は ASP.NET(サーバー側)は関係なくてクライアント側の問題と思っていたのですが、上のレスを拝見するとサーバーも関係ありそうな感じで、質問者さんのレスにあった、
> コードの差を考えたとき、こちらで現象発生するコードは大きな画面の一部で、他にもボタンやリストビュー
> などが配置されているのですが、
というところが関係しているのかもしれませんね。> 試していただいたコードをこちらでも動かしてみたところ現象発生しませんでした。
ということで、問題の原因はその差分にあるのでしょうから、「大きな画面」などのコードを少しずつ削っていったら問題の部分が特定できるのではないでしょうか? 現在いただいている情報では何が起こっているのか分からず、すみませんが、その程度のこと(プラス、前のレスで提案した 2 度押し防止を実装して様子を見ること)しか提案できません。
> 現象発生時のパケットは再度確認してみますが、
HTTP 通信をキャプチャするなら、Wireshark より Fiddler2 をお勧めします。
Wireshark は、昔と変わってなければ、localhost トラフィックをキャプチャすることができませんので、ローカルの IIS とローカルのブラウザを使って行う Web アプリ開発には使い難いという問題があります。
IE9 以降なら Fiddler2 で localhost トラフィックをキャプチャできますので、開発マシンで実行してキャプチャした結果を見ながらデバッグすることができます。
> その後のデータが返ってきていない状態でした。前の非同期要求の応答が帰ってこないうちに再度非同期要求をかけると、ブラウザ側では前の処理は Abort されますが、サーバー側は前の要求の処理を続けて行い応答を返します。
Fiddler2 で見ると、例えば私のサンプルで、ボタンを複数回クリックして要求をかけると、全ての要求に対し 10 秒後に応答が返ってくるのが分かります。
ただし、ブラウザに表示されるのは、一番最後にボタンクリックして非同期要求をかけたときの応答になります。
> UpdatePanel内に別なボタンなどがいると、クリックしたときに何か関係して
> くるものなのでしょうか?他にどんなオブジェクトがあろうと、クリックの処理内で更新したオブジェクト
> 以外には変化ないものと思っていたのですが・・・。ScriptManager + UpdatePanel を使って非同期ポストバックをかけた場合と、普通に同期ポストバックをかけた場合で、ブラウザからの送信の内容とサーバー側の動作は全く同じになります。
違うのは、サーバーからの応答が UpdatePanel 内の html ソースと ViewState を更新するためのデータになること、ブラウザ側では UpdatePanel 内のみ(ViewState もですが)書き換えることだけです。
[ASP.NET AJAX]UpdatePanelコントロール利用時の注意点とは?[2.0のみ、C#、VB]
http://www.atmarkit.co.jp/fdotnet/dotnettips/672aspajaxasyncpost/aspajaxasyncpost.htmlなので、「しつこく連打」されるとサーバー側でいろいろなところに影響して、問題が起こることはあり得ます。(ただ、その結果 IE がフリーズするような問題が起こるのかはわかりませんが)
- 編集済み SurferOnWww 2015年7月24日 1:28 一部修正
- 回答としてマーク 星 睦美 2015年7月28日 2:34
すべての返信
-
300万件の処理?は、正常に動作した場合どのくらい時間がかかる処理ですか?
また、どのくらいの頻度(秒間何回くらいとか)で、何回くらい連続クリックすると発生しますか?
あと、現象が発生するのは、デバッグ実行かそうでないか、どちらの場合かなど分かりますか?
※ASP.NETのUpdatePanel内でのポストバックって、前回の処理が終わらないうちに再度起こった場合、どう動作しましたっけね?
いくつか動作や現象に関連しそうな事項はないこともなくて、
・通常同一サーバへのリクエストは同時に2つまでしか行えない(行わない)ので、IE側で待ちが詰まっていくかも
・ASP.NETでは同一セッションの処理はシリアル化されるので、前の処理が終わるまで次のリクエストが処理されず、処理待ちが詰まるかも
・もしかしたらサーバ側のセキュリティ関連の何かで切断されることがあり得ないこともないかも(ただしIEの設定が普通で2リクエスト同時まで程度ならあまり考えにくい気もする)
・デバッグ実行だと他に何か引っかかることがあるかも
とかとか。
--追記
今どきではIE(その他の多くのブラウザもそうっぽい?)デフォルト6接続とかになっているんですね。
訂正しておきます。
- 編集済み なちゃ 2015年7月24日 5:21
-
SurferOnWwwさん、なちゃさん、返信ありがとうございます。
説明不足で申し訳ありません。
> サーバ側のボタンクリック処理に300万カウント行うDo~Loop処理
についてですが、
「連続クリックしていると、ポストバックしなくなるような現象が発生し、IEを再起動しないと復旧しない状態になる」
という現象があって、調べるにあたって普通に連続クリックしてもなかなか発生させられないため、サーバ側から
すぐに応答を返せない状況を無理やり作り出せば発生しやすくなるのでは?という想定から追加した処理です。
300万回ループするだけの中身は空の処理です。
インターネットを見ていると、PageRequestManagerのget_isInAsyncPostBackを使っての2重クリック防止の
処置方法などはあるのですが、ASP.NETでは必ず入れなければならない処置なのか?とか、処置しなかった場合
上記のような現象が起こりうるのか?などの情報が探し出せなかったため、ご存知の方がいないかと投稿させて
いただきました。
知りたかったのは、
・ASP.NETではボタンをしつこく連打していると、「ポストバックしなくなるような現象が発生し、IEを再起動しないと
復旧しない状態になる」 ような現象が発生するのは何故なのか
・そういうことも起こりえるので、「ASP.NETでは2重クリック防止処置は必須の処置である」 といった結論が
成り立つものなのか
です。
-
> すぐに応答を返せない状況を無理やり作り出せば発生しやすくなるのでは?という想定から追加した処理です。
それで問題は再現できたのでしょうか?
ちなみに、自分は以下のようなコードで試して見ましたが(環境は開発マシンの Vista SP2 32-bit, IIS7, ASP.NET 4, IE9 です)、自力でマウスでボタンをポチポチする程度では、ポストバックできなくなることはなかったですし(あまり早く連打すると一部スキップされることもありましたが)、まして IE を再起動しないと復旧しないということもありませんでした。
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Button_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(10000); } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> UpdatePanel <br /> <%=DateTime.Now.ToString()%> <br /> <asp:Button ID="Button1" runat="server" Text="Update" OnClick="Button_Click" /> </ContentTemplate> </asp:UpdatePanel> </form> </body> </html>
IE9 の同時接続数はデフォルトで 6 ですが(IE8 以降は 2 ではなく 6 になってます)、自力でマウスでボタンをポチポチするような操作で限度を超えてそれが問題を起こすということはなさそうな感じです。
「すぐに応答を返せない状況」というのは実際にどのくらいの時間か分かりませんが、デフォルトのタイムアウト 90 秒を超えるのでしょうか? そうだとすると話はまた違ってくるのかもしれませんが・・・
以上のようなわけで、質問に対する答えは出せないので、また質問になってしまって済みませんが、
> ・ASP.NETではボタンをしつこく連打していると、「ポストバックしなくなるような現象が発生し、
> IEを再起動しないと復旧しない状態になる」 ような現象が発生するのは何故なのか「すぐに応答を返せない状況」をコードに加えて問題は再現できたのでしょうか? であれば、その時間は何秒でしょう? 上記のコードでその時間を Thread.Sleep(xxxxx) の xxxxx に設定して問題が再現できますか? 再現できるとすると「しつこく連打」は具体的にどのように行ったのでしょうか?
> ・そういうことも起こりえるので、「ASP.NETでは2重クリック防止処置は必須の処置である」 と
> いった結論が成り立つものなのか「IEを再起動しないと復旧しない状態になる」といった理由で 2 度押し(実際は「しつこく連打」と理解していますが)防止をするという話は少なくとも自分は聞いたことがありません。
本当に「しつこく連打」と関係があるのか否かを確認するため、2 度押し防止を実装して様子を見たらいかがでしょう。応答が帰ってくるまでは「しつこく連打」してもブラウザから要求は出ないので、試した結果でヒントが得られるかもしれません。
ご存知だと思いますが、ご参考に 2 度押し防止の具体例を紹介しておきます。
二度押し防止
http://surferonwww.info/BlogEngine/post/2010/12/12/Cancel-request-using-PageRequestManager.aspx- 編集済み SurferOnWww 2015年7月22日 13:22 一部追記
-
返信遅く申し訳ないです。
>> すぐに応答を返せない状況を無理やり作り出せば発生しやすくなるのでは?という想定から
>>追加した処理です。
>それで問題は再現できたのでしょうか?
再現しています。ループ回数を300万回と書きましたが、もっと増やすとすぐに発生する状況です。
リクエスト発行からループ処理(回数増やして3億回)して、サーバから返ってくるまでの時間は
2秒ほどで、Thread.Sleepへの置換えは試せていませんがやってみようと思います。
「しつこく連打」は具体的には、フリーのマウストレーサを使って1分ほどの連打(秒間3~4回)記録を
連続再生させたり、4倍速再生など使ったりしています。
2度押し防止の処置をしての調査はこれからやってみようと考えています。
試していただいたコードをこちらでも動かしてみたところ現象発生しませんでした。パケットのデータを
みたところ、連打し終わった最後のクリックのPOSTとそれに対するAckがあり10秒後にHTTPの
200 OKが返ってきています。連打中のデータは接続(SYN)、POST、切断(RST)を繰返しているので、
これを見るとRSTは先発の要求をキャンセルするために出ているような気がしてきました。
現象発生時のパケットは再度確認してみますが、POSTに対するAckはあるが、その後のデータが返って
きていない状態でした。
コードの差を考えたとき、こちらで現象発生するコードは大きな画面の一部で、他にもボタンやリストビュー
などが配置されているのですが、それらのクリックを途中挟み込む操作などはしていないので関係ない
ものと考えていましたが、UpdatePanel内に別なボタンなどがいると、クリックしたときに何か関係して
くるものなのでしょうか?他にどんなオブジェクトがあろうと、クリックの処理内で更新したオブジェクト
以外には変化ないものと思っていたのですが・・・。
-
最初は ASP.NET(サーバー側)は関係なくてクライアント側の問題と思っていたのですが、上のレスを拝見するとサーバーも関係ありそうな感じで、質問者さんのレスにあった、
> コードの差を考えたとき、こちらで現象発生するコードは大きな画面の一部で、他にもボタンやリストビュー
> などが配置されているのですが、
というところが関係しているのかもしれませんね。> 試していただいたコードをこちらでも動かしてみたところ現象発生しませんでした。
ということで、問題の原因はその差分にあるのでしょうから、「大きな画面」などのコードを少しずつ削っていったら問題の部分が特定できるのではないでしょうか? 現在いただいている情報では何が起こっているのか分からず、すみませんが、その程度のこと(プラス、前のレスで提案した 2 度押し防止を実装して様子を見ること)しか提案できません。
> 現象発生時のパケットは再度確認してみますが、
HTTP 通信をキャプチャするなら、Wireshark より Fiddler2 をお勧めします。
Wireshark は、昔と変わってなければ、localhost トラフィックをキャプチャすることができませんので、ローカルの IIS とローカルのブラウザを使って行う Web アプリ開発には使い難いという問題があります。
IE9 以降なら Fiddler2 で localhost トラフィックをキャプチャできますので、開発マシンで実行してキャプチャした結果を見ながらデバッグすることができます。
> その後のデータが返ってきていない状態でした。前の非同期要求の応答が帰ってこないうちに再度非同期要求をかけると、ブラウザ側では前の処理は Abort されますが、サーバー側は前の要求の処理を続けて行い応答を返します。
Fiddler2 で見ると、例えば私のサンプルで、ボタンを複数回クリックして要求をかけると、全ての要求に対し 10 秒後に応答が返ってくるのが分かります。
ただし、ブラウザに表示されるのは、一番最後にボタンクリックして非同期要求をかけたときの応答になります。
> UpdatePanel内に別なボタンなどがいると、クリックしたときに何か関係して
> くるものなのでしょうか?他にどんなオブジェクトがあろうと、クリックの処理内で更新したオブジェクト
> 以外には変化ないものと思っていたのですが・・・。ScriptManager + UpdatePanel を使って非同期ポストバックをかけた場合と、普通に同期ポストバックをかけた場合で、ブラウザからの送信の内容とサーバー側の動作は全く同じになります。
違うのは、サーバーからの応答が UpdatePanel 内の html ソースと ViewState を更新するためのデータになること、ブラウザ側では UpdatePanel 内のみ(ViewState もですが)書き換えることだけです。
[ASP.NET AJAX]UpdatePanelコントロール利用時の注意点とは?[2.0のみ、C#、VB]
http://www.atmarkit.co.jp/fdotnet/dotnettips/672aspajaxasyncpost/aspajaxasyncpost.htmlなので、「しつこく連打」されるとサーバー側でいろいろなところに影響して、問題が起こることはあり得ます。(ただ、その結果 IE がフリーズするような問題が起こるのかはわかりませんが)
- 編集済み SurferOnWww 2015年7月24日 1:28 一部修正
- 回答としてマーク 星 睦美 2015年7月28日 2:34