• Авторизация


Асинхронное выполнение длительных операций и взаимодействие с UI - Quick & Dirty 25-10-2007 19:37 к комментариям - к полной версии - понравилось!


[476x115]
Не секрет что время от времени приходится кодировать достаточно длительные операции. Реализация таких операций напрямую в обработчике пользователя ведёт к блокированию пользовательского интерфейса. Соответственно логично запускать подобные действия в отдельном потоке (нитке). При этом с особым пиететом надо относится к взаимодействию данного процесса с элементами пользователького интерфейса. Дело в том что элементы пользовательского интерфейса потоконебезопасны и доступ к ним надо синхронизировать. Ниже приведён достаточно элегантный вариант реализации подобного взаимодействия. Основное "волшебство" находится в строчках 58-76. Новый поток образуется посредством вызова метода BeginInvoke (стр. 75) у анонимного делегата (стр 64-74). Для взаимодействия с элементами пользовательского интерфейса используется SynchronizationContext.Send (стр 72 и 74), выполняющего в свою очередь анонимные делегаты в потоке UI...

    1 using System;
    2 using System.Drawing;
    3 using System.Threading;
    4 using System.Windows.Forms;
    5 
    6 public class AsyncExecutionDemoForm : Form
    7 {
    8     private Button startButton;
    9     private ProgressBar progressBar;
   10 
   11     public AsyncExecutionDemoForm()
   12     {
   13         createUI();
   14     }
   15 
   16     private void createUI()
   17     {
   18         startButton = new Button();
   19         progressBar = new ProgressBar();
   20         SuspendLayout();
   21         // 
   22         // startButton
   23         // 
   24         startButton.Anchor = ((AnchorStyles.Top | AnchorStyles.Bottom)
   25                               | AnchorStyles.Left)
   26                              | AnchorStyles.Right;
   27         startButton.Location = new Point(168, 50);
   28         startButton.Name = "startButton";
   29         startButton.Size = new Size(127, 23);
   30         startButton.TabIndex = 0;
   31         startButton.Text = "Поехали!";
   32         startButton.UseVisualStyleBackColor = true;
   33         startButton.Click += new EventHandler(startButton_Click);
   34         // 
   35         // progressBar
   36         // 
   37         progressBar.Anchor = (AnchorStyles.Top | AnchorStyles.Left)
   38                              | AnchorStyles.Right;
   39         progressBar.Location = new Point(8, 12);
   40         progressBar.Name = "progressBar";
   41         progressBar.Size = new Size(447, 23);
   42         progressBar.TabIndex = 1;
   43         progressBar.Style = ProgressBarStyle.Continuous;
   44         // 
   45         // AsyncExecutionDemoForm
   46         // 
   47         AutoScaleDimensions = new SizeF(6F, 13F);
   48         AutoScaleMode = AutoScaleMode.Font;
   49         ClientSize = new Size(468, 88);
   50         Controls.Add(progressBar);
   51         Controls.Add(startButton);
   52         Name = "AsyncExecutionDemoForm";
   53         Text = "AsyncExecutionDemoForm";
   54         ResumeLayout(false);
   55     }
   56 
   57 
   58     void startButton_Click(object sender, EventArgs e)
   59     {
   60         SynchronizationContext sc = SynchronizationContext.Current;
   61         // Заблокируем кнопку
   62         startButton.Enabled = false;
   63         ((SendOrPostCallback)
   64          delegate(object delay)
   65              {
   66                  // Что-то делаем
   67                  for (int i = 0; i < 100; ++i)
   68                  {
   69                      // Имитируем бурную деятельность
   70                      Thread.Sleep((int) delay);
   71                      // Обновляем UI в правильном потоке
   72                      sc.Send(delegate { progressBar.Value = i + 1; }, null);
   73                  }
   74                  sc.Send(delegate { startButton.Enabled = true; }, null);
   75              }).BeginInvoke(100, null, null);
   76     }
   77 
   78 
   79     [STAThread]
   80     static void Main()
   81     {
   82         Application.EnableVisualStyles();
   83         Application.SetCompatibleTextRenderingDefault(false);
   84         Application.Run(new AsyncExecutionDemoForm());
   85     }
   86 }


Дополнительно рекомендуются к ознакомлению:
вверх^ к полной версии понравилось! в evernote


Вы сейчас не можете прокомментировать это сообщение.

Дневник Асинхронное выполнение длительных операций и взаимодействие с UI - Quick & Dirty | dimzon541 - Поток не замутненного разумом сознания... | Лента друзей dimzon541 / Полная версия Добавить в друзья Страницы: раньше»