news 2026/11/1 0:32:07

ASP.NET DropDownList多选报错?一文详解根因与5种解决方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ASP.NET DropDownList多选报错?一文详解根因与5种解决方案

前两天在群里看到有人被这个报错卡了一下午,正好我刚帮一个同事排查过同样的异常,就把它仔细说透。在 ASP.NET Web Forms 的世界里,"不能在 DropDownList 中选择多个项"(Cannot select multiple items in a DropDownList)是一个出现频率极高的经典错误。它通常发生在页面渲染阶段,症状很独特:编译能过,IDE 不报警,一旦运行页面直接黄屏,异常堆栈指向 DropDownList 的渲染逻辑。更让人困惑的是,很多人在代码里并没有显式写"多选"两个字,结果依然触发,这是因为绑定数据后给多个列表项做了 Selected=true 的操作,同样会被判定为多选。这篇文章我会从错误现场、控件设计根因、五种可落地的替换方案到常见坑位排查,完整走一遍,适合正在维护老项目的人,也适合准备面试时被问到"DropDownList 和 ListBox 有什么区别"的同学参考。

1. 错误表象与问题定位

1.1 报错到底是什么时候冒出来的

先还原一下现场。错误信息中英文对照大概是这样的:

  • 英文:System.Web.HttpException: Cannot select multiple items in a DropDownList.
  • 中文:异常详细信息: System.Web.HttpException: 不能在 DropDownList 中选择多个项。

这个异常不是在编译期抛出来的,而是在页面生命周期走到Render(渲染)阶段才炸。也就是说,你用 Visual Studio 生成项目、甚至把页面跑起来,前面绑定数据、回发事件都正常,但只要浏览器请求到达服务器端渲染 HTML 的那一步,异常就出来了。这个时机决定了它的迷惑性:很多人排查的时候先在后台代码里找原因,找了半天发现逻辑都没问题,才开始怀疑控件本身。

触发它常见的有三种写法。

第一种,直接在 aspx 标记里声明多选属性:

<asp:DropDownList ID="ddlCity" runat="server" SelectionMode="Multiple"> </asp:DropDownList>

第二种,在后台代码里给 SelectionMode 赋值:

ddlCity.SelectionMode = ListSelectionMode.Multiple;

第三种,绑定数据后同时让多个项处于选中状态:

ddlCity.Items.FindByValue("beijing").Selected = true; ddlCity.Items.FindByValue("shanghai").Selected = true;

前两种是最直观的"手动开启多选";第三种是我同事踩的最多的写法:业务上要回显历史选择,写了循环给很多 item 打上 Selected 标记,结果页面一刷新就黄屏。从代码语义上看,你要"多选",DropDownList 就直接拒绝渲染。

1.2 为什么第一反应"修不好"

这个错误的第一个坑在于:很多人第一反应是去给控件加一个multiple属性,像写原生 HTML 那样。但 ASP.NET Web Forms 的 DropDownList 服务端控件并没有开放这个属性,你在 aspx 标记里写multiple="multiple",解析阶段大概率会报"属性无效";就算绕过了解析,最终渲染出来的 select 标签也依然只有一个单选下拉。

第二个常见的错误修复姿势,是去改 CSS 或者加 Bootstrap 样式。有人觉得 DropDownList 渲染出来的就是一个<select>,那我用 CSS 给它增加高度、展示成列表不就行了?问题是服务端控件在渲染前就已经做了多选校验,你根本等不到浏览器渲染的那一刻,服务端就抛异常了。所以这条路完全行不通。

第三个低级但高频的坑,是复制代码时闹出的乌龙。很多老项目的页面里既有 DropDownList 又有 ListBox,从 ListBox 那段复制了带SelectionMode="Multiple"的代码,粘到 DropDownList 上忘了改控件类型,结果自然踩雷。

1.3 这个错误的高发场景

结合我在项目里看到的实际情况,出问题最多的是这三类场景:

  • 老系统改造:把 ListBox 换成 DropDownList 节省页面空间,但是绑定回显逻辑没跟着改,循环里给多个项设了 Selected。
  • 动态生成控件:后台用代码new DropDownList()创建下拉列表,顺手设置了 SelectionMode,运行到渲染时直接炸。
  • 前后端混合页:前端通过 JS 把 select 的 multiple 属性加上去,想着提交的时候服务端能收数组,但服务端控件校验根本不给你机会。

如果你也遇到的是这三类情况,恭喜你,问题其实很明确:DropDownList 这类控件从根本上就不允许多选,别在这个控件上继续纠结,直接往下看替代方案。

2. 根因:DropDownList 和 ListBox 是天生两类控件

2.1 继承关系里藏着答案

要理解这个错误,先看一眼 ASP.NET Web Forms 服务端控件的继承关系。DropDownList 和 ListBox 都继承自System.Web.UI.WebControls.ListControl。

System.Web.UI.WebControls.ListControl ├── DropDownList (固定单选) └── ListBox (支持单选/多选)

ListControl 基类承担了很多公共能力:管理 Items 集合、处理 SelectedValue、SelectedIndex、以及数据绑定相关的 DataSource 等。它也提供了一个SelectionMode属性,类型是ListSelectionMode枚举,包含Single和Multiple两个值。正是因为SelectionMode定义在基类里,DropDownList 天然继承到了这个属性,所以你在后台代码里写:

ddlCity.SelectionMode = ListSelectionMode.Multiple;

编译器和 IDE 都不会报错,因为属性确实存在。但 DropDownList 的内部实现里,把自身写死成只能单选,渲染阶段一旦发现 SelectionMode 不是 Single,就直接抛出 HttpException。这就是"编译能过、运行报错"的完整解释。

2.2 HTML 里 select 标签的双面性

从浏览器这端看,事情更有意思。原生 HTML 的<select>标签到底支持不支持多选?支持,但通过multiple属性和size属性控制。一旦给 select 加上multiple或把size设成大于 1,它就不再是"点击展开的单行下拉",而是变成一个"滚动列表框"。

ASP.NET Web Forms 做控件封装时,把这两种 UI 形态拆成了两个不同的服务端控件:一个负责"单行下拉 + 单选交互",就是 DropDownList;一个负责"滚动列表 + 单选/多选交互",就是 ListBox。换句话说,多选从来不是 DropDownList 的职责范围,而是 ListBox 的。搞清楚这个映射关系,很多困惑都能化解。

你的页面需求原生 HTML 方案ASP.NET 控件方案SelectionMode 设置
下拉单选<select>DropDownList不支持设置 Multiple
列表多选<select multiple>ListBoxMultiple
列表单选<select size="n">ListBoxSingle
复选平铺一组<input type="checkbox">CheckBoxList无该概念,使用 Checked

2.3 一个生活化类比

我一直喜欢把这两个控件比作购物场景。DropDownList 就像自动售货机,一次只能掉出来一罐饮料,你投币、选择、出货,流程固定;ListBox 就像超市货架,你可以同时往购物车里拿好几样东西,哪怕货架大小有限,你也能上下翻看全部商品。CheckBoxList 则更像是购物清单,每一项前面打个勾,一眼能看清所有选项。

需求是"一次只能选一个城市"就用 DropDownList,需求是"一次选多个城市"就要换 ListBox 或者其他平铺复选控件。这个设计定位决定了我们再怎么调参数也没办法把自动售货机变成超市货架,只能换工具。

3. 五个能落地的解决方案

3.1 方案一:换成 ListBox 控件,代码改动最小

如果页面布局能接受"滚动列表"这种展示形式,方案一最简单粗暴:把 DropDownList 直接换成 ListBox,并把 SelectionMode 设为 Multiple。改动成本极低,服务端读取逻辑也是现成的。

前台代码如下:

<asp:ListBox ID="lstCity" runat="server" SelectionMode="Multiple" Rows="8"> </asp:ListBox>

后台绑定和回显:

protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // 绑定数据源 lstCity.DataSource = GetCityList(); lstCity.DataTextField = "Text"; lstCity.DataValueField = "Value"; lstCity.DataBind(); // 回显默认选中的城市 string[] defaultValues = { "beijing", "shanghai" }; foreach (string value in defaultValues) { ListItem item = lstCity.Items.FindByValue(value); if (item != null) { item.Selected = true; } } } }

提交时获取全部选中值:

protected void btnSubmit_Click(object sender, EventArgs e) { List<string> selectedValues = lstCity.Items .Cast<ListItem>() .Where(i => i.Selected) .Select(i => i.Value) .ToList(); }

这里有一个很重要的坑:不要用SelectedValue取多个选中值。ListBox 即使处于多选状态,SelectedValue也只返回第一个选中项,想拿到全部值必须遍历 Items 集合过滤Selected为 true 的项。我见过不少新人在这里偷懒,取到的永远只有第一个值,排查半天还以为是控件没传值。

ListBox 有个Rows属性,用来控制可视行数,如果不设置,多选状态下默认可能只显示两行左右,用户体验很差,建议显式设置成 6 到 10 行。另外,ListBox 的宽高是相对固定的,不能用 CSS 把它变成"点击展开"的下拉形态,如果产品经理坚持要下拉外观,请看方案三。

3.2 方案二:用 CheckBoxList 平铺复选项

当页面是"设置页""筛选条件面板"这类场景,不一定要下拉形态,用 CheckBoxList 平铺复选反而更直观。CheckBoxList 本身没有"多选"的概念,每一项就是一个 CheckBox,用户勾选哪些项就是哪些项,服务端获取逻辑和 ListBox 类似。

前台代码:

<asp:CheckBoxList ID="cblCity" runat="server" RepeatColumns="3" RepeatDirection="Horizontal"> </asp:CheckBoxList>

后台获取选中值:

List<string> selectedValues = cblCity.Items .Cast<ListItem>() .Where(i => i.Selected) .Select(i => i.Value) .ToList();

CheckBoxList 的优势是:不用关心 ViewState 回传后选中状态是否丢失的问题(只要 ViewState 开启),交互上用户也一眼能看出是多选。劣势是它占用的页面空间比较大,如果城市列表有几十个项,平铺下来会非常难看。这时候可以配合RepeatColumns属性控制每行列数,比如 4 列、6 列,视觉上会紧凑很多。

从功能对比的角度看,CheckBoxList 和 ListBox 的区别在于:ListBox 在视觉上仍然是"一个整体列表",适合需要按住 Ctrl 或 Shift 多选的场景;CheckBoxList 则把每一个选项独立展示,鼠标逐个点选即可,对普通用户更友好。我的经验是,如果选项数不超过 15 个,优先用 CheckBoxList;超过 15 个,用 ListBox 更节省空间。

3.3 方案三:需求非得是"下拉多选",自己组装一个

很多实际项目里,产品经理会说:"我就要那种点开一个下拉框,里面可以勾选多个选项的效果。"这种 UI 在今天的 Vue、React 项目里到处都是,但如果在老 Web Forms 项目里硬做,也是有办法的。核心思路是:不用 DropDownList,而是用 TextBox + 浮层 + 复选框 + HiddenField 组合。

页面结构大致如下:

<asp:TextBox ID="txtCityDisplay" runat="server" ReadOnly="true" placeholder="请选择城市" CssClass="form-control" autocomplete="off"></asp:TextBox> <asp:HiddenField ID="hfCityValues" runat="server" /> <div id="cityDropdownPanel" class="dropdown-panel" style="display:none;"> <asp:CheckBoxList ID="cblCityPopup" runat="server"></asp:CheckBoxList> </div>

JavaScript 部分负责三件事:展开/收起浮层、勾选时把值写入 HiddenField、点击页面其他区域时关闭浮层。

// 展开收起 document.getElementById('<%= txtCityDisplay.ClientID %>').addEventListener('click', function (e) { var panel = document.getElementById('cityDropdownPanel'); panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; e.stopPropagation(); }); // 勾选时更新显示值和隐藏字段值 var checkboxes = document.querySelectorAll('#cityDropdownPanel input[type="checkbox"]'); function syncSelected() { var values = []; var labels = []; checkboxes.forEach(function (cb) { if (cb.checked) { values.push(cb.value); labels.push(cb.closest('label').innerText.trim()); } }); document.getElementById('<%= hfCityValues.ClientID %>').value = values.join(','); document.getElementById('<%= txtCityDisplay.ClientID %>').value = labels.join(', '); } checkboxes.forEach(function (cb) { cb.addEventListener('change', syncSelected); }); // 点击页面其他区域关闭 document.addEventListener('click', function (e) { var container = document.getElementById('cityDropdownPanel'); var txt = document.getElementById('<%= txtCityDisplay.ClientID %>'); if (!container.contains(e.target) && e.target !== txt) { container.style.display = 'none'; } });

服务端读取时,从 HiddenField 拿到逗号分隔的字符串:

string rawValues = hfCityValues.Value; List<string> selectedValues = rawValues .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .ToList();

这个方案有几个细节需要注意:第一,HiddenField 的值是逗号拼接的字符串,如果选项值本身可能包含逗号,就要在业务层约定好规范,或者改用|这类分隔符;第二,回发之后 HiddenField 的值会自动保留(它本身就是服务端控件),但 CheckBoxList 的状态要自己根据 HiddenField 恢复;第三,浮层的定位建议用position:absolute挂在 TextBox 下方,并且要给浮层设置一个较高的z-index,否则会被后面的控件盖住。

这套方案看起来代码多一些,但它是纯 Web Forms 技术栈里实现"下拉多选"最可控的方式,不依赖任何第三方库,兼容性也最好。我在一个 2012 年的老项目里就是这么改造的,几百个用户用下来没有遇到兼容性问题。

3.4 方案四:引入现成前端组件,Web Forms 也能用

如果说页面里刚好引用了 jQuery,另一个思路是直接用现成的前端多选下拉组件,比如 Select2、Bootstrap Select 等。这类组件本身不是为 Web Forms 设计的,接入时要遵循一个核心原则:组件用于视觉和交互,数据交给服务端控件或 HiddenField 承载。

比较稳妥的接入方式是:在页面上放一个普通的多选 ListBox,然后对 ListBox 调用 Select2 做增强。Select2 会把 ListBox 渲染成漂亮的下拉多选框,用户勾选时数据仍然同步到 ListBox 的选中项上,提交时服务端照常遍历 ListBox 的 Items 即可。

页面代码示例:

<asp:ListBox ID="lstCity" runat="server" SelectionMode="Multiple" style="width:100%;"> </asp:ListBox>

JavaScript 初始化:

$(function () { $('#<%= lstCity.ClientID %>').select2({ placeholder: '请选择城市', allowClear: true }); });

服务端读取和方案一完全一样,不需要额外处理。这是我认为最省事的"体面方案":交互体验接近现代组件,服务端又不用改动太多逻辑。

但这里一定要说清楚两个坑。第一,Select2 会修改原始 select 的 DOM 结构,如果在服务端回发前用户做了很多次勾选,要确保 select 元素本身的值被正确同步。实测下来,Select2 的事件机制会自动把选中的 option 标成 selected,所以服务端读取没问题,但如果你在同一个页面上又用别的 JS 去读取 select.value,可能会发现值和显示不一致。第二,引入了前端组件就得管理好 CSS 和 JS 的加载顺序,老项目如果已经有一堆脚本文件,Select2 的样式和全局样式冲突是常有的事,排查起来挺费时间。

所以我的建议是:如果项目里本来就用了 Bootstrap 并且已经引入了 jQuery,那就放心用 Select2;如果项目是纯后端渲染、几乎没有前端依赖,那还是用方案三自己组装更省心,毕竟为一个小功能引入一整套前端组件有点得不偿失。

3.5 方案五:如果根子上是"数据接收"问题

最后一种情况比较特别。有时候后端要接收的就是"多个值",比如一个接口接收cityIds=1,2,3,前端页面根本没有必要用"下拉多选"这种复杂交互,完全可以让用户在一组复选框中选完,提交时把选中的 id 拼成逗号分隔字符串,后端再 Split。这也是方案二变体,但从架构层面看,它避开了"控件是否支持多选"的问题。

例如后端只需要从这个字段取值:

public class CityQueryModel { public string CityIds { get; set; } } public List<int> GetCityIdList() { return CityIds .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(int.Parse) .ToList(); }

这种方式很适合前后端已经分离、只有个别老页面在用 Web Forms 的场景。前端页面继续用传统控件收集值,后端用字符串接收,两端都无非标准操作,代码简单,也不容易踩服务端控件的限制。如果你的页面只是中间过渡,后面整体要迁到新前端框架,这个方案最省事,过渡期不要在这类页面上投入太多改造精力。

4. 常见问题排查与避坑技巧

4.1 用 SelectedValue 拿不到全部选中值

前面提过,这里再强调一下。ListControl 的SelectedValue属性在设计上就是"获取当前选中项的值",在多选场景下它返回的只是第一项。很多人在 ListBox 多选状态下直接写:

string value = lstCity.SelectedValue;

拿到"北京"还觉得是对的,等再选一个"上海"发现值没变,就开始怀疑是不是回传数据有问题。实际上,多选取值只有一条正路:遍历 Items,过滤Selected == true。

var selected = lstCity.Items.Cast<ListItem>().Where(i => i.Selected);

顺带说一句,SelectedIndex在多选状态下也有同样的问题,它只返回第一个选中项的索引。凡是"单数"语义的属性,在多选场景里都得小心。

4.2 ViewState 被禁用后,选中状态悄悄丢失

Web Forms 依赖 ViewState 保存控件状态。ListBox 和 CheckBoxList 的选中状态,在回发后就是靠 ViewState 还原的。如果页面在某个环节把 ViewState 关了(比如设置了EnableViewState="false"),你会发现第一次绑定和勾选都正常,一旦点击提交按钮回发,所有选中项全部丢失,或者只能拿到最后一次操作的数据。

排查方法很直接:打开浏览器开发者工具,看页面源码里有没有__VIEWSTATE这个隐藏字段;如果字段为空,多半是 ViewState 被关了或页面被压缩时过滤掉了。

解决办法有两个方向。一是不要用 ViewState 保存选中状态,改为在每次回发时重新绑定数据并手动恢复选中项。恢复逻辑放在Page_Init或者PreLoad事件里,不要在Page_Load中记录,因为Page_Load触发时状态已经加载完,又会被后面的逻辑覆盖。二是如果项目允许,直接打开控件的 ViewState,进页面时只绑定一次,之后回发都靠 ViewState 还原,这是 Web Forms 最省心的默认用法。

我见过不少新人对 ViewState 有莫名的恐惧,全页面统一EnableViewState="false",结果遇到这类问题。其实 ViewState 是 Web Forms 的特性,正确使用它,别滥用,就没有问题。

4.3 数据绑定时机不对,回显总是少一刀

另一种高发问题是:数据绑定的代码写在了!IsPostBack外面,也就是说每次回发都会重新绑一次数据源。结合上面 ViewState 的机制,会出现一个诡异现象:页面第一次加载回显正常,回发后选中状态恢复失败,或者所有项变成未选中。

原因在于:第一次加载时控件里已经绑定了数据项,回发后控件状态还在 ViewState 里,此时你再次调用 DataBind,会重新生成 Items,把原来的选中状态冲掉。标准写法是:

protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { BindCityList(); // 只在第一次加载时绑定 RestoreSelectedCities(); // 回显默认选中 } }

如果非要每次回发都重新绑定,那必须在绑定完成后重新设置选中项,且要注意时机在Load事件之后、触发其他事件之前,否则事件处理里读到的选中状态可能是旧的或空的。

4.4 回发时服务端能不能直接拿到前端选中的多值

原生 select 多选在表单提交时,同一 name 会传多个值。ASP.NET 的 Request.Form 在读取这种字段时,会把多个值合并成逗号分隔的字符串。比如用户选了"北京"和"上海",你写:

string rawStr = Request.Form["lstCity"];

拿到的可能是"beijing,shanghai"。这不是控件故意做成这样的,而是 ASP.NET 处理表单集合时的既定行为。知道了这个机制,你在调试时可以绕过控件直接看原始表单数据,能更快定位到底是控件没回传值,还是服务端读取方式不对。

4.5 常见问题速查表

现象可能原因解决思路
编译通过,运行时抛出 Cannot select multiple itemsDropDownList 被设置了 Multiple 或多个项 Selected=true换成 ListBox 或 CheckBoxList
页面黄屏,异常指向 DropDownList.Render标记或代码里写了 SelectionMode=Multiple把控件换成 ListBox
ListBox 多选回发后只拿到一个值用了 SelectedValue 而不是遍历 Items遍历 Items 过滤 Selected
回发后所有选中项丢失ViewState 被禁用或重复 DataBind调整绑定时机,恢复 ViewState
CheckBoxList 平铺太占页面空间RepeatColumns 未设置设置 RepeatColumns 列数
Select2 样式混乱全局 CSS 冲突隔离组件样式或改用自绘方案
自绘下拉多选点空白处不关闭事件监听绑定不正确在 document 上绑定 click 事件并判断目标区域

4.6 调试建议:别让异常只留一句黄屏

最后分享几个调试技巧。Web Forms 页面抛出这种异常时,默认黄页信息有限,尤其是发布环境可能直接显示"Runtime Error",连堆栈都没有。建议在Global.asax的Application_Error里统一抓一下异常:

protected void Application_Error(object sender, EventArgs e) { var ex = Server.GetLastError(); // 记录 ex.ToString() 到日志文件 LogHelper.Error(ex.ToString()); // 清理异常,避免页面继续展示黄页 Server.ClearError(); }

另外,在排查控件回传问题时,可以在页面上加一个临时按钮,把Request.Form里的所有键值输出到页面,直观地看到底收到了哪些字段、值是什么格式:

var sb = new StringBuilder(); foreach (string key in Request.Form.AllKeys) { sb.AppendFormat("{0}: {1}<br/>", key, Request.Form[key]); } litDebug.Text = sb.ToString();

这种原始数据能帮你分清"控件没传"和"读取姿势不对"两种问题。我在实际项目里靠这个方法解决过好几个类似的多选回传问题,比看控件属性靠谱得多。

结尾:一点个人经验

做 Web Forms 维护做了这么多年,这种"编译通过、运行报错"的控件限制类问题,我遇到的还真不少。每次排查这类问题,我都会先想清楚一件事:这个控件在设计时锁定了什么能力,而不是看它表面上暴露了什么属性。DropDownList 的属性管得再宽,它的核心定位就是单选下拉,遇到多选需求,最优解永远是换控件而不是硬改它。我自己后来只要看到"下拉多选"需求,直接就是 ListBox + Select2 或者自绘浮层,很少再跟 DropDownList 较劲。最后一个经验之谈:写代码时如果循环给 DropDownList 的多个项打 Selected 标签,那基本就是在埋雷,一定要养成给控件类型做注释的习惯,或者干脆一开始就评估清楚使用场景,选对控件,后面的坑会少一半。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/1 0:32:06

基于Flask的北京旅游信息管理平台开发复盘:从数据模型到部署实践

做外包这些年&#xff0c;接到的管理系统需求五花八门&#xff0c;但像“北京旅游信息管理平台”这种项目&#xff0c;几乎每年都会碰到几次。表面看就是一个信息管理系统&#xff1a;把北京主要景点的资料、游客评论、推荐路线管起来。实际上手之后才会发现&#xff0c;真正费…

作者头像 李华
网站建设 2026/11/1 0:32:02

WorkBuddy实战:把重复劳动变成可复用的自动工作流

1. 先读懂 WorkBuddy 的定位&#xff1a;它不是“又一个大模型聊天框”这几年AI工具我接触了不少&#xff0c;从纯问答助手到各类叠加了插件能力的写作工具&#xff0c;大部分是用完即走&#xff1a;问一个问题&#xff0c;拿到一段答案&#xff0c;关掉页面&#xff0c;第二天…

作者头像 李华
网站建设 2026/10/25 13:33:29

微信小程序影院购票系统毕设全解析:源码、架构与答辩

每年这个时候&#xff0c;朋友圈就会冒出一批被毕设折磨到凌晨三点的人。如果你正在做基于微信小程序的影院购票管理系统毕业设计&#xff0c;或者身边有朋友在找这类源码&#xff0c;那这篇东西应该能帮到你。我会从选题思路、技术选型、数据库设计、核心接口、小程序端实现到…

作者头像 李华
网站建设 2026/10/21 7:41:09

端侧 WebGPU 推理基准报告:主流移动端与桌面端 GPU 算力实测盘点

在过去半年里&#xff0c;前端圈关于“把大模型搬进浏览器”的讨论铺天盖地。从 WebLLM、Transformers.js 到各大自研推理框架&#xff0c;几乎都在宣扬端侧 AI 的免服务器成本、绝对数据隐私和零网络延迟。然而&#xff0c;作为需要对线上性能与转化率负责的技术手艺人&#x…

作者头像 李华
网站建设 2026/10/26 0:29:11

Simulink智能车辆局部路径规划与DWA避障仿真实战解析

如果你最近也在用Simulink做智能车辆方向的课程作业或者比赛项目&#xff0c;应该和我有同感&#xff1a;Simulink上手不难&#xff0c;难的是把一个“完整场景”跑通——尤其是局部路径规划这种既要建模又要控制还要可视化的活儿。我上个月刚完成了一个基于Simulink的智能车辆…

作者头像 李华