C# 在c-Wpf中循环大量图像时计算机冻结

C# 在c-Wpf中循环大量图像时计算机冻结,c#,wpf,backgroundworker,dispatcher,C#,Wpf,Backgroundworker,Dispatcher,所以我有一个非常简单的软件来调用多图像列表 并以下一个+上一个格式显示它们,如下所示: 这对我来说非常有用,但当我按住“下一步”按钮快速传递所有项目时,在10或20个项目之后,整个窗口会冻结和延迟,一些recherche说要使用后台工作程序来防止出现这种情况,所以我尝试插入以下内容: var getImage = Directory.EnumerateFiles(DirName, Ext, SearchOption.TopDirectoryOnly); 其中: 但同样的问题仍在发生 如何使其正

所以我有一个非常简单的软件来调用多图像列表 并以下一个+上一个格式显示它们,如下所示:

这对我来说非常有用,但当我按住“下一步”按钮快速传递所有项目时,在10或20个项目之后,整个窗口会冻结和延迟,一些recherche说要使用后台工作程序来防止出现这种情况,所以我尝试插入以下内容:

var getImage = Directory.EnumerateFiles(DirName, Ext,
SearchOption.TopDirectoryOnly);
其中:

但同样的问题仍在发生

如何使其正确工作?
如果还有其他方法,我很乐意知道。

Dispatcher.Invoke计划在UI线程上执行委托。您不希望在UI线程上执行任何可能长时间运行的代码,因为这会冻结您的应用程序

如果要在后台线程上调用Directory.EnumerateFiles,可以启动任务:

Task.Factory.StartNew(()=> 
{
    //get the files on a background thread...
    return Directory.EnumerateFiles(DirName, Ext, SearchOption.TopDirectoryOnly);
}).ContinueWith(task => 
{
    //this code runs back on the UI thread
    IEnumerable<string> theFiles = task.Result; //...
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());

请注意,您无法访问后台线程上的任何UI控件,因此您应该只在后台线程上执行长时间运行的工作,然后如果您希望在UI线程上返回结果,可以使用ContinueWith方法,例如,设置ItemsControl的ItemsSource属性,或将ProgressBar的Visibility属性设置回折叠状态或其他状态。

Dispatcher.Invoke计划在UI线程上执行委托。您不希望在UI线程上执行任何可能长时间运行的代码。你为什么要这么做?@mm8我想它会比BackgroundWorker=新的BackgroundWorker更好;但是我对调度员和后台工作人员也没有足够的了解,这就是为什么我问:如果有其他方法可以避免我调用我的图像时出现延迟,你可以与我们分享:,这是一个知识平台,我们就是为此而来的。您应该在后台线程上执行任何长时间运行的操作,但请记住,您只能在UI线程上访问UI元素。请参考我的答案了解更多信息。首先,你不应该使用BackgroundWorker。使用Task.Run可以更轻松地完成它所能做的一切。Stephen Cleary有一系列关于为什么应该使用Task.Run而不是BackgroundWorker的文章@NewellClark::谢谢你们两位,我尝试了这个方法,在这里查看我的回复,也许我们可以找到一个好方法:谢谢它让我的预览速度更快,延迟也减少了,但长时间按住“下一步”按钮后窗口仍然冻结:/,我在想,这可能是因为图像在显示后需要保存在Thumbs.db的%Temp%中,这样图像就不需要每次软件查看时都重新计算,你怎么想?为什么要投否决票?在UI线程上执行的任何操作都会降低应用程序的响应速度,因为它无法响应鼠标移动和按钮单击等事件,也无法同时执行自定义代码。因此,您需要减少调用单击事件处理程序的频率,将它正在执行的任何工作卸载到后台线程,或者以某种方式使其更快。没有捷径。
Task.Factory.StartNew(()=> 
{
    //get the files on a background thread...
    return Directory.EnumerateFiles(DirName, Ext, SearchOption.TopDirectoryOnly);
}).ContinueWith(task => 
{
    //this code runs back on the UI thread
    IEnumerable<string> theFiles = task.Result; //...
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());