C#代码遇空文本框无法生成词列表的问题求助
嘿,我来帮你解决这个问题!你的核心痛点在于当某个替换列表为空时,对应的Parallel.ForEach循环根本不会执行内部逻辑——哪怕你的模板里完全不需要这个标记。咱们一步步来修复代码,顺便解决隐藏的线程安全问题:
问题根源拆解
比如deList为空时,最内层的Parallel.ForEach(deList, ...)会直接跳过所有操作,哪怕你的模板里没有(DE)标记,后续的替换、添加操作也完全跑不起来。另外还有个隐藏坑:List<string>和StringBuilder都不是线程安全的,多线程并行操作时会导致数据错乱或者丢失。
修复后的代码
private void GenerateButton_Click(object sender, EventArgs e) { // 1. 处理空列表:为空的列表添加空字符串,确保循环至少执行一次 var kwList = kw1.kw.Lines.ToList(); if (!kwList.Any()) kwList.Add(string.Empty); var wordList = wordtypes1.wordtypelist.Lines.ToList(); if (!wordList.Any()) { MessageBox.Show("You need to have at least 1 wordtype!"); return; } var ptList = pt1.ptlist.Lines.ToList(); if (!ptList.Any()) ptList.Add(string.Empty); var pfList = pf1.pflist.Lines.ToList(); if (!pfList.Any()) pfList.Add(string.Empty); var deList = de1.delist.Lines.ToList(); if (!deList.Any()) deList.Add(string.Empty); var sfList = sf1.sflist.Lines.ToList(); if (!sfList.Any()) sfList.Add(string.Empty); // 2. 改用线程安全的集合存储结果,避免并发操作出错 var uniqueWords = new ConcurrentDictionary<string, byte>(); var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = threads }; // 3. 优化并行逻辑:外层用Parallel,内层用普通foreach(避免过度嵌套导致线程过载) Parallel.ForEach(wordList, parallelOptions, word => { foreach (var kw in kwList) { foreach (var kw2 in kwList) { foreach (var pf in pfList) { foreach (var pt in ptList) { foreach (var sf in sfList) { foreach (var de in deList) { var currentWord = word; // 按顺序替换标记 currentWord = currentWord.Replace("(KW)", kw); currentWord = currentWord.Replace("(KW2)", kw2); currentWord = currentWord.Replace("(PF)", pf); currentWord = currentWord.Replace("(PT)", pt); currentWord = currentWord.Replace("(SF)", sf); currentWord = currentWord.Replace("(DE)", de); // 自动去重:TryAdd仅当单词不存在时才添加 uniqueWords.TryAdd(currentWord, 0); } } } } } } }); // 4. 拼接结果并写入文件 var content = string.Join(Environment.NewLine, uniqueWords.Keys); var fileName = $"generated{filenumber}.txt"; System.IO.File.WriteAllText(fileName, content); MessageBox.Show($"Generated words are saved to {fileName}"); }
关键优化点说明
- 空列表处理:给每个空列表添加一个空字符串,这样循环至少会执行一次。如果模板里没有对应标记,替换空字符串不会改变模板内容,完美适配你的需求。
- 线程安全:用
ConcurrentDictionary<string, byte>替代原来的List<string>,既保证多线程操作安全,又能通过TryAdd高效实现去重(比List.Contains性能好很多)。 - 并行逻辑优化:过度嵌套
Parallel.ForEach会创建大量线程,反而降低性能。这里外层用Parallel.ForEach处理模板列表,内层用普通foreach,平衡并行效率和资源开销。
内容的提问来源于stack exchange,提问作者Thiplol
相关产品推荐
相关产品推荐

