c# - 迭代不断修改的 List
问题描述
所以我正在从我的 arduino 读取一个恒定的串行数据流来验证我程序中的一些东西。但是显示这些会锁定 UI 线程。所以我的“解决方案”是制作一个保存串行数据的缓冲区,然后使用计时器将数据以间隔而不是恒定流放在 UI 线程上。
我的代码:
public partial class ConsoleWindow : Window
{
private SerialPort _serialPort;
private List<string> bufferStrings = new List<string>();
private readonly DispatcherTimer timer = new DispatcherTimer();
public ConsoleWindow(ref SerialPort serialPort)
{
InitializeComponent();
if (serialPort != null)
{
timer.Interval = new TimeSpan(0,0,0,0,80);
timer.Tick += PopQueue;
_serialPort = serialPort;
_serialPort.DataReceived += DataReceived;
timer.Start();
}
}
private void PopQueue(object sender, EventArgs e)
{
var queue = bufferStrings;
foreach (var queueString in queue)
{
AppendText(queueString);
}
bufferStrings.Clear();
}
private void DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (_serialPort != null)
{
bufferStrings.Add(((SerialPort)sender).ReadLine());
//AppendText(((SerialPort) sender).ReadLine());
}
}
public void AppendText(string text)
{
Application.Current.Dispatcher.Invoke(() =>
{
if (Output.Inlines.Count > 100)
{
Output.Inlines.Remove(Output.Inlines.FirstInline);
}
Output.Inlines.Add(text);
ScrollViewer.ScrollToBottom();
});
}
}
这个问题是我得到一个例外:System.InvalidOperationException: 'Collection was modified; enumeration operation may not execute.'
. 我知道它为什么会发生,但我不知道如何正确地做到这一点。也不知道要谷歌什么。
解决方案
您可以采取以下两种解决方案来防止InvalidOperationException
:
- 在遍历其内容之前将缓冲区复制到一个新列表。
var queue = bufferStrings.ToList();
您可以通过调用注意来做到这一点,您必须包括using System.Linq;
才能使用ToList()
. lock
通过用关键字包围迭代线程来使迭代线程安全:private void PopQueue(object sender, EventArgs e) { lock(bufferStrings) { foreach (var queueString in bufferStrings) { AppendText(queueString); } bufferStrings.Clear(); } } private void DataReceived(object sender, SerialDataReceivedEventArgs e) { if (_serialPort != null) { lock(bufferStrings) { bufferStrings.Add(((SerialPort)sender).ReadLine()); //AppendText(((SerialPort) sender).ReadLine()); } } }
推荐阅读
- sql-server - 如何用 varchar 计算,null
- scala - 将一个数据帧的数组列与scala中另一个数据帧的数组列的子集进行比较
- python - NameError:名称“assigs”未定义
- python - 如何打印不带空格的元组(2,1,4)的整数
- phpstorm - 如何将 PhpStorm 的主题重置为默认值?
- java - 如何使用 Jenkins 参数向属性文件添加值
- javascript - Pacman 游戏:检查和更新二维数组有效位置 - Javascript
- python - 识别 PDF 层
- c# - 如何以传统方式封装 web api 响应 int .netcore api
- opencart - 在 opencart 上将图像添加到主题