Winforms: избегать заморозки приложения - PullRequest
2 голосов
/ 15 ноября 2009

Я делаю некоторые операции с «большим» файлом (около 4 Мб)

Я делаю это: 1. Получить все файлы из каталога и поместить их в IList MyInfoClass имеет свойства: имя, расширение, fullPath, creationDate, contentPart 2. Я делаю запрос Linq, чтобы получить только какой-то тип расширения. 3. Я зацикливаюсь на результате запроса Linq и для каждого открываю файл, выполняю некоторую операцию (получаем значение) и помещаю результат в MyFileIno.ContentPart.

К вашему сведению: 30 файлов, это 14-секундная операция

Это работа.

Проблема, когда я запускаю свою библиотеку из пользовательского интерфейса, когда я нажимаю кнопку, окно останавливается во время работы. Я хотел бы:

  1. решение не замораживать форму
  2. см. Ход выполнения

Не могли бы вы дать мне лучшую практику для решения такого рода проблем?

Спасибо

код

public class FileManager 
{
    public string CurrentFileName { get; set; }
    public void Validation(string path)
    {
        IList<InfoFile> listFile = GetListFile(path);
        foreach (InfoFile item in listFile)
        {
            CurrentFileName = item.Name;
            .....
        }
    }
}


private void button1_Click(object sender, EventArgs e)
{
    var worker = new BackgroundWorker();
    worker.DoWork += (s, args) =>
    {
        int percentProgress = 6;
        FileManager fileManager = new FileManager();
        fileManager.Validation(@"C:.....");
        ((BackgroundWorker)s).ReportProgress(percentProgress, fileManager.CurrentFileName);
    };

    worker.ProgressChanged += (s, args) =>
    {
        var currentFilename = (string)args.UserState;
        label1.Text = currentFilename;
        progressBar1.Value = args.ProgressPercentage;
    };

    worker.RunWorkerCompleted += (s, args) =>
    {
        progressBar1.Value = 0;
    };
    worker.RunWorkerAsync();
}

1 Ответ

17 голосов
/ 15 ноября 2009

Приложение зависает, потому что вы выполняете анализ файла в главном потоке. Вы можете использовать BackgroundWorker для выполнения операции в новом потоке. Вот некоторый псевдокод, который может помочь вам начать:

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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...