首页 > 解决方案 > 我希望在加载大文件时避免表单冻结以显示

问题描述

我制作了自己的 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 加载大文件期间避免表单冻结的任何想法?

标签: c#formswinforms

解决方案


推荐阅读