从数据库取单行填充DataTable时触发System.StackOverflowException
问题根源与解决方案
1. 无限递归触发StackOverflowException
你忽略的核心问题是getBarcode函数的递归逻辑错误,这直接导致了栈溢出:
public string getBarcode(char c) { EncryptFuc encryptFuc = new EncryptFuc(); string barcode = encryptFuc.GenerateRandomEan13Barcode(c); if (IsContainBarcode(barcode)) { // 错误:递归调用但未返回结果,且无终止条件 getBarcode(c); } return barcode; }
问题点:
- 当生成的条码已存在时,递归调用
getBarcode(c),但没有将递归生成的新条码返回,而是继续返回原来的重复条码。 - 如果短时间内连续生成重复条码(比如当前前缀下的可用条码已接近耗尽),会触发无限递归,不断占用栈内存,最终抛出
StackOverflowException。 - 昨天正常是因为当时重复概率低,没触发无限递归;今天条码池接近耗尽,重复概率飙升,才暴露问题。
修正代码:
public string getBarcode(char c) { EncryptFuc encryptFuc = new EncryptFuc(); string barcode = encryptFuc.GenerateRandomEan13Barcode(c); if (IsContainBarcode(barcode)) { // 递归调用时返回新生成的条码 return getBarcode(c); } return barcode; }
额外优化:为了避免极端情况下的无限递归,建议添加递归次数限制:
public string getBarcode(char c, int retryCount = 0) { const int MaxRetry = 100; if (retryCount >= MaxRetry) throw new InvalidOperationException("无法生成唯一条码,可用条码池已耗尽"); EncryptFuc encryptFuc = new EncryptFuc(); string barcode = encryptFuc.GenerateRandomEan13Barcode(c); if (IsContainBarcode(barcode)) { return getBarcode(c, retryCount + 1); } return barcode; }
2. SQL注入风险
getLastBarcodeByFirstChar函数使用字符串拼接构建SQL语句,存在严重的SQL注入漏洞:
new SqlCommand($"SELECT TOP 1 barcode FROM Barcodes WHERE barcode LIKE '{c}%' ORDER BY Id DESC", Con)
修正代码(使用参数化查询):
public string getLastBarcodeByFirstChar(char c) { using (SqlConnection Con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString)) { using (SqlCommand cmd = new SqlCommand("SELECT TOP 1 barcode FROM Barcodes WHERE barcode LIKE @prefix ORDER BY Id DESC", Con)) { cmd.Parameters.AddWithValue("@prefix", $"{c}%"); Con.Open(); var result = cmd.ExecuteScalar(); return result?.ToString() ?? string.Empty; } } }
3. 冗余代码优化
原getLastBarcodeByFirstChar中用foreach遍历DataTable完全冗余,上面的修正代码改用ExecuteScalar直接获取单个结果,既简化逻辑又提升性能。
内容的提问来源于stack exchange,提问作者nawar
相关产品推荐
相关产品推荐

