C# Winforms:避免冻结应用程序

C# Winforms:避免冻结应用程序,c#,winforms,performance,C#,Winforms,Performance,我在“大”文件上做了一些操作(大约4Mb) 我这样做: 1.从目录中获取所有文件并将其放置在IList MyInfoClass中,该类具有以下属性:名称、扩展名、完整路径、creationDate、contentPart 2.我执行Linq查询只获取一些扩展类型。 3.我循环Linq查询结果,对于每个查询结果,我打开文件,执行一些操作(获取值),并将结果放入MyFileIno.ContentPart 仅供参考:30个文件,这是一个14秒的操作 这就是工作 问题是,当我从UI运行我的库时,当我单击

我在“大”文件上做了一些操作(大约4Mb)

我这样做: 1.从目录中获取所有文件并将其放置在IList MyInfoClass中,该类具有以下属性:名称、扩展名、完整路径、creationDate、contentPart 2.我执行Linq查询只获取一些扩展类型。 3.我循环Linq查询结果,对于每个查询结果,我打开文件,执行一些操作(获取值),并将结果放入MyFileIno.ContentPart

仅供参考:30个文件,这是一个14秒的操作

这就是工作

问题是,当我从UI运行我的库时,当我单击按钮时,窗口在操作期间冻结。我想:

  • 不冻结表单的解决方案
  • 查看操作的进度
  • 你能告诉我解决这类问题的最佳方法吗

    谢谢

    代码

    公共类文件管理器
    {
    公共字符串CurrentFileName{get;set;}
    公共无效验证(字符串路径)
    {
    IList listFile=GetListFile(路径);
    foreach(列表文件中的信息文件项)
    {
    CurrentFileName=item.Name;
    .....
    }
    }
    }
    私有无效按钮1\u单击(对象发送者,事件参数e)
    {
    var worker=新的BackgroundWorker();
    worker.DoWork+=(s,args)=>
    {
    整数百分比进展=6;
    FileManager FileManager=newfilemanager();
    fileManager.Validation(@“C:…”);
    ((BackgroundWorker)s).ReportProgress(percentProgress,fileManager.CurrentFileName);
    };
    worker.ProgressChanged+=(s,args)=>
    {
    var currentFilename=(字符串)args.UserState;
    label1.Text=当前文件名;
    progressBar1.Value=args.ProgressPercentage;
    };
    worker.RunWorkerCompleted+=(s,args)=>
    {
    progressBar1.值=0;
    };
    worker.RunWorkerAsync();
    }
    
    应用程序冻结,因为您正在主线程中执行文件解析。您可以使用在新线程上执行操作。以下是一些可能有助于您入门的伪代码:

    private void button1_Click(object sender, EventArgs e)
    {
        var worker = new BackgroundWorker();
        worker.DoWork += (s, args) =>
        {
            // Here you perform the operation and report progress:
            int percentProgress = ...
            string currentFilename = ...
            ((BackgroundWorker)s).ReportProgress(percentProgress, currentFilename);
            // Remark: Don't modify the GUI here because this runs on a different thread
        };
        worker.ProgressChanged += (s, args) =>
        {
            var currentFilename = (string)args.UserState;
            // TODO: show the current filename somewhere on the UI and update progress
            progressBar1.Value = args.ProgressPercentage;
        };
        worker.RunWorkerCompleted += (s, args) =>
        {
            // Remark: This runs when the DoWork method completes or throws an exception
            // If args.Error != null report to user that something went wrong
            progressBar1.Value = 0;
        };
        worker.RunWorkerAsync();
    }
    

    谢谢关于GUI的评论很好,我得到了一个例外…:)我希望处理文件名而不是percentProgress,为什么不处理百分比?您可以使用
    BackgroundWorker.ReportProgress(int,object)
    ,其中第二个参数是自定义用户状态对象,您可以通过
    args.UserState
    在我的业务类中的
    ProgressChanged
    回调中使用,在循环中,我设置了当前文件的属性。但是我从不传入“ProgressChanged”@Kris,每次调用
    ReportProgress
    方法时都会调用
    ProgressChanged
    回调,因此您需要向业务对象传递一个委托,该委托将指向ReportProgress方法,并且将定期调用该方法。
    private void button1_Click(object sender, EventArgs e)
    {
        var worker = new BackgroundWorker();
        worker.DoWork += (s, args) =>
        {
            // Here you perform the operation and report progress:
            int percentProgress = ...
            string currentFilename = ...
            ((BackgroundWorker)s).ReportProgress(percentProgress, currentFilename);
            // Remark: Don't modify the GUI here because this runs on a different thread
        };
        worker.ProgressChanged += (s, args) =>
        {
            var currentFilename = (string)args.UserState;
            // TODO: show the current filename somewhere on the UI and update progress
            progressBar1.Value = args.ProgressPercentage;
        };
        worker.RunWorkerCompleted += (s, args) =>
        {
            // Remark: This runs when the DoWork method completes or throws an exception
            // If args.Error != null report to user that something went wrong
            progressBar1.Value = 0;
        };
        worker.RunWorkerAsync();
    }