たぶん、
(1) [更新]ボタンクリックで JavaScript の btnLoopUpdClick メソッドを起動、
(2) $('#<%=this.btnUpdate.ClientID %>').click(); でポストバックがかかる、
(3) サーバー側で隠しフィールドが 1 に書き換えられて応答が返ってくる、
(4) クライアント側で隠しフィールドの値が 1 だったらループから break する
・・・ということを考えていると思いますが、(2) の後でもループは周り続けるので、応答が返ってくる前に何回も (2) でポストバックがかかるというのが問題の原因だと思います。
ScriptManager と UpdatePanel を使って、非同期ポストバックを行うようにし、非同期要求が出てから応答が返ってきて処理が終わるまでは (2) はスキップするようにしてはいかがですか?
「非同期要求が出てから応答が返ってきて処理が終わる」というのは、PageRequestManager のイベントを使って判定できます。詳しくは以下の記事を見てください。
ASP.NET PageRequestManager クラスの概要
https://learn.microsoft.com/ja-jp/previous-versions/visualstudio/visual-studio-2008/bb386571(v=vs.90)
PageRequestManager のイベントの処理
https://learn.microsoft.com/ja-jp/previous-versions/visualstudio/visual-studio-2008/bb398976(v=vs.90)
不明点があれば下のコメント欄で質問してください。
【追記】
PageRequestManager のイベントの使用例を紹介しておきます。
http://surferonwww.info/BlogEngine/post/2010/12/12/Cancel-request-using-PageRequestManager.aspx
二度押し防止
【追記2】
下のコメント欄の 2022/11/10 14:54 の私のコメントで「後で、検証に使ったサンプルコードを回答欄に追記しておきます」と書いた件です。
そもそも while(true) ループで $('#<%=this.btnUpdate.ClientID %>').click(); を繰り返すというのがダメで、下のコメントに書いたフラグ案では対処できなかったです。
以下のコードでは、[更新]ボタンクリックでは一回だけ $('#<%=this.btnUpdate.ClientID %>').click(); を行い、その応答が返ってきて OnEndRequest が呼ばれたらその中で隠しフィールドが 1 でないときは再度 $('#<%=this.btnUpdate.ClientID %>').click(); することで対応しています。
サーバー側で隠しフィールドが 1 に書き換えられる条件は、サーバー側のボタンクリックのイベントハンドラ(下のコードでは Button1_Click)が 3 回呼ばれたらとしています。カウントには ViewState を使います。
.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm11.aspx.cs"
Inherits="WebForms1.WebForm11" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script src="Scripts/jquery-3.4.1.js"></script>
<script type="text/javascript">
//<![CDATA[
var manager;
function pageLoad(sender, args) {
if (args.get_isPartialLoad() === false) {
manager = Sys.WebForms.PageRequestManager.getInstance();
manager.add_initializeRequest(OnInitializeRequest);
manager.add_endRequest(OnEndRequest);
}
}
function OnInitializeRequest(sender, args) {
}
function OnEndRequest(sender, args) {
if ($('#<%=HiddenField1.ClientID %>').val() != "1") {
$('#<%=Button1.ClientID %>').click();
}
}
function btnLoopUpdClick() {
$('#<%=Button1.ClientID %>').click();
}
//]]>
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<input type="button" id="btnLoopUpd" value="更新" onclick="btnLoopUpdClick()"/>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" Text="Button"
OnClick="Button1_Click" />
<asp:HiddenField ID="HiddenField1" runat="server" />
<asp:Label ID="Label1" runat="server"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
.aspx.cs
C#
1using System;
2
3namespace WebForms1
4{
5 public partial class WebForm11 : System.Web.UI.Page
6 {
7 int count;
8
9 protected void Page_Load(object sender, EventArgs e)
10 {
11 if (!IsPostBack)
12 {
13 ViewState["Count"] = 0;
14 Label1.Text = "初期画面";
15 }
16 else
17 {
18 count = (int)ViewState["Count"];
19 }
20 }
21
22 protected void Button1_Click(object sender, EventArgs e)
23 {
24 // ラベルの変化の途中経過が分かるように 1 秒待機
25 System.Threading.Thread.Sleep(1000);
26
27 count++;
28 if (count > 2)
29 {
30 HiddenField1.Value = "1";
31 }
32 Label1.Text = $"count: {count}, hidden: {HiddenField1.Value}";
33 ViewState["Count"] = count;
34 }
35 }
36}