c# - 我希望在加载大文件时避免表单冻结以显示
问题描述
我制作了自己的 FilePreviewHandler 来预览某些文件,例如 Explorer,因为目前我制作了自定义文件浏览器。
当我单击 ListView 上的项目时,我可以像资源管理器一样预览文件。
我的文件浏览器中的 PreviewHandler 包含用于加载电影/文本文件的 WebBrowser 类、用于加载图像文件的 PictureBox 和用于其他扩展的 ShellExPreviewHandler。
参与的问题是这样的。
当我尝试加载诸如 100mb 或更大的大文件或 8000x4000 像素之类的大图像文件时,表单会冻结,直到加载文件。
PreviewHandler 的代码区:
public void Open( String FileName )
{
if ( !Enabled || Last == FileName )
{
return;
}
//FileName = DriveUtil.RevealPath( FileName );
String FileType = MIMEAssistant.GetMIMEType( FileName );
// Image Files
if ( ImagePreviewTarget.Where( x => FileType.Contains( x ) ).Count() > 0 )
{
IsProgress = true;
try
{
if ( ImagePreviewHandler.Image != null )
{
ImagePreviewHandler.Image.Dispose();
GC.Collect();
}
Image TargetImage = Image.FromFile( FileName );
if ( TargetImage.Width > this.Width || TargetImage.Height > this.Height )
{
ImagePreviewHandler.SizeMode = PictureBoxSizeMode.Zoom;
}
else
{
ImagePreviewHandler.SizeMode = PictureBoxSizeMode.CenterImage;
}
ImagePreviewHandler.Image = TargetImage;
ImagePreviewHandler.BringToFront();
}
catch
{
ImagePreviewHandler.Image = null;
GC.Collect();
ShellExPreviewHandler.BringToFront();
IsProgress = false;
}
}
// WebPreviewArea
// This area doesn't make any problem. So I hide my codes on here.
// PdfPreviewArea
// Currently I don't use Pdf PreviewHandler. So I also hide my codes on here.
// Other extensions
else
{
ShellExPreviewHandler.Open( FileName );
ShellExPreviewHandler.BringToFront();
}
Last = FileName;
}
我尝试了什么:
我尝试为此使用 Thread、Task.Run、Backgroundworker,但所有这些都需要 MyForm.Invoke 来绘制控件。
螺纹部分 =>
Thread Preview = new Thread( (ThreadStart) =>
{
try
{
if ( FilePreview != null && Browser.PreviewOpened )
{
Console.WriteLine( "FilePreview.Open Task Start" );
FilePreview.Open( Browser.SelectedPath );
Console.WriteLine( "FilePreview.Open Task Completed" );
}
}
catch ( Exception ex )
{
Console.WriteLine( ex.StackTrace );
}
Process = false;
} );
Preview.Start();
if ( Preview.Join( TimeSpan.Zero ) )
{
DateTime dt = DateTime.Now;
TimeSpan Interval = TimeSpan.FromMilliseconds( 50 );
while ( Process )
{
if ( dt + Interval < DateTime.Now )
{
Application.DoEvents();
dt = DateTime.Now;
}
}
}
Task.Run 部分 =>
var t = Task.Run( () =>
{
try
{
this.Invoke( new MethodInvoker( delegate
{
if ( Browser.SelectedItems.Count == 0 )
{
FilePreview.Initialize();
return;
}
else if ( Browser.SelectedItems[0].ForeColor == Color.Pink )
{
FilePreview.Initialize();
return;
}
if ( FilePreview != null && Browser.PreviewOpened )
{
FilePreview.Open( Browser.SelectedPath );
}
} ) );
}
catch
{
}
} );
后台工作者 =>
private void PreviewWorker_DoWork( object sender, DoWorkEventArgs e )
{
FilePreviewHandler FilePreview = null;
GCS.Windows.Forms.FileFolderList Browser = null;
switch ( PreviewStatus ) {
case BrowserStatus.Local:
FilePreview = LocalFilePreviewHandler;
Browser = LocalBrowser;
break;
case BrowserStatus.Network:
FilePreview = NetFilePreviewHandler;
Browser = NetworkBrowser;
break;
}
if ( FilePreview == null )
{
return;
}
this.Invoke( new MethodInvoker( delegate
{
FilePreview.Open( Browser.SelectedPath );
} ) );
}
我认为这部分使我的程序冻结。
在为 PreviewHandler 加载大文件期间避免表单冻结的任何想法?
解决方案
推荐阅读
- python - 将字典字段分组在一起 Python
- html - 具有自动滚动功能的动态列固定长度
- spring - 为什么 Spring Boot 将相同的 HttpServletResponse 对象注入到我的 Controller 方法中以获得不同的请求?
- watson-studio - 使用 IBM Analytics 作为引擎调度笔记本
- ios - 如何使用更新的 UIImagePickerControllerDelegate iOS 12 API?
- java - 在我的情况下,BindingResult 或 FieldErrors 或 GlobalErrors 可以为空吗?
- windows - Windows CMD 自动使用特定程序运行命令
- javascript - VS Code中的多个命令行而不打开新窗口
- c# - 如果文件大小为0kb,gridview上不显示,文件被删除
- javascript - 如何在 JSON 文件中获取特定数据