我正在编写简单的 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动画。
发生了什么?
最佳答案
问题是呈现图片框需要您的应用程序处理它的消息。当您在 UI 线程上执行长时间阻塞操作时,表单不可能重绘自身(您阻塞了唯一一个可以进行绘图的线程)。
最简单的解决方案是避免在 UI 线程上做任何重要的工作(和/或阻塞)。您正在读取 CSV 文件 - 这可能是 I/O 受限操作。如果您使用异步 I/O 来处理文件读取,您将避免阻塞同步 I/O。使用 await
使这变得相当简单:
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
// Do your work
}
如果工作的 CPU 部分也很密集,这仍然会导致您的动画“卡顿”。要处理此问题,您可以确保完成整个加载和处理,而无需编码回 UI 线程(并且仅在绝对必要时才返回 UI 线程)。一种方法是使用 ConfigureAwait
:
string line;
while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
{
// Do your work
}
请注意,您可能希望在一个单独的方法中分离在没有访问 UI 的情况下发生的代码 - 这将使您能够通过 await
ing 该方法编码回 UI 线程反过来。
请注意,就像 Application.DoEvents
一样,这会打开您的代码以进行重入。但是,鉴于您之前显然已经使用过它,它应该不会造成很多问题。如果您使用 ConfigureAwait(false)
,通常会出现多线程警告,当然 - 您需要保持适当的同步等。
关于c# - 为什么 gif 动画无法在图片框 c# windows 应用程序中启动动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30432606/