Asp.Net/VB.Net中ImageButton加载延迟,快速点击引发异常
问题描述
开发《Deal or No Deal》类开箱游戏,代码部署在UpdatePanel中,共处理22个盒子按钮。快速点击ImageButton时出现两类问题:
- 部分按钮无法更新为
openBox样式 - 部分按钮提前执行
session("BoxValueX")=0,导致生成不存在的图片路径~/files/images/icons/boxes/MONMOpenBox0.png
清除设备图片缓存后问题更容易触发,推测与图片加载速度不足有关。
相关代码
前端ASPX代码
<asp:ImageButton ID="btnBox1" visible="false" cssclass="playboxsize" commandArgument="1" ImageUrl="~/files/images/icons/boxes/MONMClosedBox1.png" runat="server" onClick="btnBoxSelected_Click" /> <asp:ImageButton ID="btnBox2" visible="false" cssclass="playboxsize" commandArgument="2" ImageUrl="~/files/images/icons/boxes/MONMClosedBox2.png" runat="server" onClick="btnBoxSelected_Click" /> <asp:ImageButton ID="btnBox3" visible="false" cssclass="playboxsize" commandArgument="3" ImageUrl="~/files/images/icons/boxes/MONMClosedBox3.png" runat="server" onClick="btnBoxSelected_Click" />
VB.Net后端代码
Protected Sub btnBoxSelected_Click(sender As Object, e As System.EventArgs) Dim btn As ImageButton = CType(sender, ImageButton) Dim boxNo As Integer = btn.CommandArgument If session("round")="chooseBoxes" Then Select Case boxNo Case"1" btnBox1.imageUrl="~/files/images/icons/boxes/MONMOpenBox" & session("BoxValue1") & ".png" btnBox1.enabled="false" session("ValueOpened")=session("BoxValue1") session("BoxValue1")=0 Case"2" btnBox2.imageUrl="~/files/images/icons/boxes/MONMOpenBox" & session("BoxValue2") & ".png" btnBox2.enabled="false" session("ValueOpened")=session("BoxValue2") session("BoxValue2")=0 Case"3" btnBox3.imageUrl="~/files/images/icons/boxes/MONMOpenBox" & session("BoxValue3") & ".png" btnBox3.enabled="false" session("ValueOpened")=session("BoxValue3") session("BoxValue3")=0 End Select End If End Sub
解决方案
1. 前端立即禁用按钮,阻止重复点击
给每个ImageButton添加客户端点击事件,点击后立即禁用按钮,避免快速触发多次回发:
<asp:ImageButton ... OnClientClick="this.disabled=true; return true;" ... />
或者封装成通用函数复用:
function disableBoxBtn(btn) { btn.disabled = true; return true; // 确保服务器端事件正常执行 }
按钮引用:
<asp:ImageButton ... OnClientClick="return disableBoxBtn(this);" ... />
2. 调整Session操作顺序,避免值被提前覆盖
当前代码先设置图片URL再将Session值设为0,并行回发时可能导致后续请求读取到已被修改的0值。先读取原始值再修改Session:
Case"1" Dim currentValue As String = session("BoxValue1") ' 先使用原始值设置图片 btnBox1.imageUrl="~/files/images/icons/boxes/MONMOpenBox" & currentValue & ".png" btnBox1.enabled="false" session("ValueOpened")=currentValue session("BoxValue1")=0
3. 预加载所有开箱图片
页面加载时通过JavaScript预加载所有openBox系列图片,避免缓存未命中时的加载延迟:
window.onload = function() { // 替换为游戏中所有可能的盒子值范围 var boxValues = [1,2,3,4,5,...]; boxValues.forEach(function(val) { var preloadImg = new Image(); preloadImg.src = '<%= ResolveUrl("~/files/images/icons/boxes/MONMOpenBox") %>' + val + '.png'; }); };
4. 服务器端增加重复操作校验
处理请求前先检查按钮状态和Session值,避免重复执行操作:
Case"1" ' 仅当按钮可用且Session值未被重置时执行 If btnBox1.Enabled AndAlso session("BoxValue1") <> 0 Then Dim currentValue As String = session("BoxValue1") btnBox1.imageUrl="~/files/images/icons/boxes/MONMOpenBox" & currentValue & ".png" btnBox1.enabled="false" session("ValueOpened")=currentValue session("BoxValue1")=0 End If
5. 处理不存在的图片场景
添加默认开箱图片,当Session值为0时使用默认图,避免404错误:
Dim currentValue As String = session("BoxValue1") If currentValue = "0" Then btnBox1.imageUrl="~/files/images/icons/boxes/MONMOpenBoxDefault.png" ' 替换为你的默认图路径 Else btnBox1.imageUrl="~/files/images/icons/boxes/MONMOpenBox" & currentValue & ".png" End If
内容的提问来源于stack exchange,提问作者Eggybread
相关产品推荐
相关产品推荐

