真的不可能在异步线程中运行动画 GIF 吗?

Posted

技术标签:

【中文标题】真的不可能在异步线程中运行动画 GIF 吗?【英文标题】:Really impossible to run animated GIF in async threads? 【发布时间】:2021-03-11 02:56:48 【问题描述】:

我想在 Spinner GIF 旋转时运行持久的方法,甚至包含耗时的 dll。

好的,最被接受的解决方案是在主线程中显示 GIF 的同时在 BackgroundWorker 中运行这些方法,我已经成功地完成了,但是……但我仍然很想知道是否真的不可能反其道而行之!

这将简化对这些方法的调用,特别是如果它们有参数和返回值,避免使用 Invoke 如果它们包含标签来显示工作进度等......

我花了很多时间浏览网页,但所有建议的解决方案都对我不起作用:一旦程序调用我的方法,Spinner 就会停止旋转并仅在方法结束时恢复工作。

Ciao,感谢您的任何建议。

【问题讨论】:

您不能在非 UI 线程上进行 UI 工作,所以是的,它真的是不可能的。它也与 GIF 完全无关。 另外,我会怀疑任何链接到该代码项目的人,因为它说“在 C# 中,每个对象都有自己的线程和......”这实际上是不正确的(而且不能更远现实)。 我强烈怀疑这是不可能的,但是按照爱因斯坦的那句话“每个人都知道这是不可能的,直到一个不知道的傻瓜出现并做到了”,我认为值得一问。跨度> @FrancoLanguasco 我建议您删除指向 codeproject 的链接(这是非常错误的“在 C# 中,每个对象都有自己的线程和......”)并发布您自己的代码。 【参考方案1】:

完成!!

感谢 Camilo Terevinto 的一句话“你不能在非 UI 线程上进行 UI 工作”,我问自己是否不可能创建在另一个线程中保存我的旋转 GIF 的 PictureBox 并且......

我创建了一个新的无边框表单(名为 frmSpinner),其中包含运行 Spinner.gif 的 PictureBox。

然后我在主窗体中使用长时间运行的方法,BackgroundWorker 在 DoWork 事件中具有 frmSpinner.Show()。

现在 Spinner 无限旋转而不会中断和恢复。

我还没有解决如何将 Spinner Form 放置在主 Form 上的正确位置的问题,但是在 PointToScreen 方法的帮助下,应该不难。

Ciao,感谢您的建议。

【讨论】:

【参考方案2】:

在 WPF/c# 项目中显式处理线程并不规范,除非您有非常具体的事情要做,否则使用 Tasks 是现代方式。

你可以有一个后台任务,例如:

Task.Run(() =>

    // blocking methods running outside UI thread
    var newPropValue = //... update a UI property
    Application.Current.Dispatcher.Invoke(() =>
    
        //Running in UI thread.
        PropValue = newPropValue;
    );
);

使用此模式,您可以从 UI 线程中移除所有繁重/阻塞的工作,并获得流畅的 UI 体验。

【讨论】:

对不起,我对 C# 编码比较陌生,但我不明白我必须更新我懒惰的 PictureBox 的哪个属性才能说服它运行 Spinner 而不会中断。但很可能我完全误解了你的答案,除非你建议我在一个单独的任务中运行持久的方法。 Task.Run 将在 UI 线程外执行 lambda 函数,但调度程序将允许您以非常简单的方式在 UI 线程内执行/更新(您不能更新 UI 对象/property 来自 lambda,仅与调度程序一起使用)。它适用于 UI 中使用的任何对象的任何属性。任何阻塞的东西都应该在任务中运行,在调度程序之外。所以,只需按照您需要的方式使用它。 我想尝试一下您的代码,但我在 Application.Current 处遇到编译器错误;浏览网页看起来这是特定于 WPF 的;有人建议添加对 PresentationFramework 的引用,我做到了,但没有运气。任何提示?谢谢。 @FrancoLanguasco 确保你有一个 WPF 项目/库,它应该是无痛的;请注意,单元测试项目中没有Application.Current。实际上,您需要添加对程序集 PresentationFramework 和 PresentationCore (docs.microsoft.com/en-us/dotnet/api/…) 的引用。

以上是关于真的不可能在异步线程中运行动画 GIF 吗?的主要内容,如果未能解决你的问题,请参考以下文章

java 多线程问题 真的提高了效率吗?

龙卷风 python 的简单异步示例

nodejs真的是单线程吗?

(一二一)核心动画基础

Play Framework 1.2.4 在异步线程中同步作业:可能吗?

node真的是单线程模式吗