我正在编写简单的Windows应用程序来调用任何数据,我已经完成了这个,打开文件对话框并读取csv文件并完成,一切都没问题,但我希望更改我的应用程序一点,我想要设置在文件读取过程中加载动画,我写这段代码:
var reader = new StreamReader(File.OpenRead(openFileDialog1.FileName), Encoding.GetEncoding(1256));
LoadForm frm = new LoadForm();
frm.Show();
Application.DoEvents();
while (!reader.EndOfStream)
{
}
并进入加载表单我把图片框和设置加载gif图像,但当我触发按钮并加载LoadForm在该表单图片框中没有动画图像并显示我静态加载GIF图像,但当我复制该图片框其他形式,图片框启动加载gif动画。
会发生什么?
答案 0 :(得分:1)
问题是渲染图片框需要您的应用程序处理其消息。当您在UI线程上执行长时间阻止操作时,表单无法重绘自己(您正在阻止可以执行绘图的唯一线程)
最简单的解决方案是避免在UI线程上做任何重要的工作(和/或阻塞)。您正在阅读CSV文件 - 这可能是I / O限制的操作。如果使用异步I / O来处理文件读取,则可以避免阻塞同步I / O.使用await
会使这变得相当简单:
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
// Do your work
}
如果工作的CPU部分也很密集,这仍然会导致你的动画“断断续续”#34;。要处理这个问题,您可以确保完成整个加载和处理,而无需编组回UI线程(并且只在必要时才返回到UI线程)。一种方法是使用ConfigureAwait
:
string line;
while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
{
// Do your work
}
请注意,您可能希望在不使用单独方法访问UI的情况下分离发生的代码 - 这将使您能够通过await
方法将该方法编组回UI线程转动。
请注意,就像Application.DoEvents
一样,这会打开您的代码以进行重入。但是,鉴于您之前显然已经使用过它,它不应该造成很多问题。如果您使用ConfigureAwait(false)
,通常需要保持正确的同步等通常的多线程警告。