我试图使我的GUI线程在长时间运行的操作期间保持响应。这些操作必须是同步的,因为它们通常是必须完成才能完成请求操作的操作。
我试图使用后台工作程序、监视器和锁对象来实现此目的。基本上,我想在长时间运行的过程开始之前启动计时器,在后台线程中启动长时间运行的过程,并等待后台工作线程表示已完成,然后继续执行相关代码。如果长时间运行的过程时间太长,则向用户显示“正在加载…”对话框,以便他们知道应用程序没有崩溃。
这种情况的一个例子可能是用户在图形包中单击按钮,必须从磁盘加载大型图像,然后我们才能在其上绘制图像并打印计算出的一百万位小数的pi值。
我无法将从磁盘加载图像异步化,这会使UI保持响应,因为用户可能启动另一个操作,从而破坏程序状态(即撤消操作)。
我可以简单地将光标更改为沙漏形状并完成它,但在许多情况下,我还希望用户能够取消操作-一个带有取消按钮的“正在加载…”对话框会很好地处理这个问题。
最初我想要的是使用锁对象和System.Threading.Monitor.Enter(),使UI线程等待直到长时间运行的线程完成,然后它继续执行。如果计时器在长时间运行的线程完成之前触发,则UI线程仍然可用于处理事件并在屏幕上绘制对话框框。
我遇到的问题是,在UI线程尝试获取锁之前,我无法让后台工作程序锁定对象。
相当恼人的是,我正在使用一些非常黑盒的第三方代码进行处理。因此,我无法将代码调整为线程友好,并报告其进度或支持取消。
我的问题 是否有任何经过验证的方法来包装第三方代码,以便UI线程保持响应,并且如果需要,我可以显示取消对话框?-有许多情况下,长时间运行的操作几乎立即完成,不需要显示对话框。
稍微澄清一下 为什么我要这样做?异步操作是Windows应用程序的宠儿...
好吧,我不想在启动长时间运行的异步操作时锁定用户界面的每个方面,然后在完成时解锁每个方面。我可以-通过设置光标或物理禁用所有按钮等等,但实际上我更喜欢能够简单地将调用包装在“某个对象/方法等”中,如果(且仅当)操作需要时间长到足以影响用户时,将允许对话框弹出。我不必担心执行流程的更改,我仍然(总体上)能够在代码中维护原子操作(不分割回调),并且仍然具有“响应”UI。
我试图使用后台工作程序、监视器和锁对象来实现此目的。基本上,我想在长时间运行的过程开始之前启动计时器,在后台线程中启动长时间运行的过程,并等待后台工作线程表示已完成,然后继续执行相关代码。如果长时间运行的过程时间太长,则向用户显示“正在加载…”对话框,以便他们知道应用程序没有崩溃。
这种情况的一个例子可能是用户在图形包中单击按钮,必须从磁盘加载大型图像,然后我们才能在其上绘制图像并打印计算出的一百万位小数的pi值。
我无法将从磁盘加载图像异步化,这会使UI保持响应,因为用户可能启动另一个操作,从而破坏程序状态(即撤消操作)。
我可以简单地将光标更改为沙漏形状并完成它,但在许多情况下,我还希望用户能够取消操作-一个带有取消按钮的“正在加载…”对话框会很好地处理这个问题。
最初我想要的是使用锁对象和System.Threading.Monitor.Enter(),使UI线程等待直到长时间运行的线程完成,然后它继续执行。如果计时器在长时间运行的线程完成之前触发,则UI线程仍然可用于处理事件并在屏幕上绘制对话框框。
我遇到的问题是,在UI线程尝试获取锁之前,我无法让后台工作程序锁定对象。
相当恼人的是,我正在使用一些非常黑盒的第三方代码进行处理。因此,我无法将代码调整为线程友好,并报告其进度或支持取消。
我的问题 是否有任何经过验证的方法来包装第三方代码,以便UI线程保持响应,并且如果需要,我可以显示取消对话框?-有许多情况下,长时间运行的操作几乎立即完成,不需要显示对话框。
稍微澄清一下 为什么我要这样做?异步操作是Windows应用程序的宠儿...
好吧,我不想在启动长时间运行的异步操作时锁定用户界面的每个方面,然后在完成时解锁每个方面。我可以-通过设置光标或物理禁用所有按钮等等,但实际上我更喜欢能够简单地将调用包装在“某个对象/方法等”中,如果(且仅当)操作需要时间长到足以影响用户时,将允许对话框弹出。我不必担心执行流程的更改,我仍然(总体上)能够在代码中维护原子操作(不分割回调),并且仍然具有“响应”UI。
我可以理解为什么我迄今为止在将BackgroundWorker/Thread制作成同步阻塞线程方面不成功,但我担心我将不得不走GUI线程中的while(true){ sleep() }
路线,而不是使用锁。