Привет всем. Совсем недавно начал изучать работу с потоками в WPF и возникли немного вопросов, на которые, надеюсь, смогу ответить с вашей помощью. Задача программы выполнить определенную работу каждые 10 секунд. Разбить эту работу на несколько частей используя потоки (Task) и при этом использовать BackgroundWorker чтобы пользовательский интерфейс не зависал во время выполнения работ. В интернете нашел много пример работы с тасками, но не смог найти несложные примеры, которые бы обьяснили как таски правильно использовать с таймером, BackgroundWorker и локами конечно. Для ясности привожу пример, которую написал, чтобы вы могли посмотреть и посоветовать правильно ли написан код. Благодаря вашим советам я смогу лучше понять как работает многопоточность в WPF. Жду с нетерпением ваших сообщением. Буду благодарен за любую предоставленную помощь.
| Код | namespace timer_and_thread { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { DispatcherTimer TimerObject; Task[] tasks; readonly object _countLock = new object(); int[] Summ = new int[10]; int Index = 0; public MainWindow() { InitializeComponent(); TimerObject = new DispatcherTimer(); TimerObject.Tick += new EventHandler(timer_Elapsed); TimerObject.Interval = new TimeSpan(0, 0, 10); } // вызвать метод каждые 10 секунд private void timer_Elapsed(object sender, EventArgs e) { TimerObject.Stop(); BackgroundWorker backgroundWorkerObject = new BackgroundWorker(); backgroundWorkerObject.DoWork += new DoWorkEventHandler(StartThreads); backgroundWorkerObject.RunWorkerAsync(); TimerObject.Start(); } private void StartThreads(object sender, DoWorkEventArgs e) { tasks = new Task[4]; tasks[0] = Task.Factory.StartNew(() => DoSomeLongWork()); tasks[1] = Task.Factory.StartNew(() => DoSomeLongWork()); tasks[2] = Task.Factory.StartNew(() => DoSomeLongWork()); tasks[3] = Task.Factory.StartNew(() => DoSomeLongWork()); // Даем задачам 1 секунду для их запуска Thread.Sleep(1000); } private void DoSomeLongWork() { while (Index < Summ.Length) { int localIndex = 0; // блокируем глобальную переменную Index lock (_countLock) { localIndex = Index; Index++; } // Я написал простой пример работы. Тут может быть большая вычислительная работа. Random rnd = new Random(); int someResult = rnd.Next(1, 100000); // блокируем глобальную переменную Summ для записи в нее вычисленного результата lock (_countLock) { Summ[localIndex] = someResult; } } } // Кнопка, с помощью которой запускаю таймер и начинается работа приложения private void Start_Button_Click_1(object sender, RoutedEventArgs e) { TimerObject.Start(); } } }
|
|