Показаны сообщения с ярлыком потоки. Показать все сообщения
Показаны сообщения с ярлыком потоки. Показать все сообщения

вторник, 11 августа 2015 г.

Показ окна в отдельном потоке

Время от времени в приложении появляются "долгие операции" во время которых интерфейс тормозит и пользователь не понимает что происходит с приложением. Обычно такие операции выносятся в фоновый поток, а в основном потоке приложения показываем прогресс выполнения работы или некую анимацию дающую понять, что приложение не повисло. Но что делать, если работа выполняется в основном потоке и вынести ее в фоновый нельзя (например, идет чтение из визуальных компонентов)? Вот об этом и поговорим под катом.

четверг, 19 сентября 2013 г.

Что делать, если запуск потоков зависит от событий, которые не реализуют уведомления?

Сегодня будет небольшой пример на многопоточность, в ответ на вопрос с форумов MSDN.
Задача состоит в том, что есть внешний источник информации, который говорит нам сколько потоков запускать, также там есть информация о том, готово ли все для запуска или нет. Если таким источником данных является MS SQL сервер, то узнать о том, что там поменялась информация мы можем только обратившись за ней сами. Все, перехожу к примеру.

четверг, 5 сентября 2013 г.

"Медленные" свойства

Свойства, как правило, достаточно просты, но предлагаю сразу не переставать читать, а посмотреть на то, что будет подкатом.
А там будет общая информация о свойствах , но, самое главное будет о том, что делать, если свойство "медленное", т.е. на присвоение или чтение надо очень много времени.

воскресенье, 3 марта 2013 г.

Упрощения жизни в примере показа всплывающих сообщений


В прошлой статье, был пример разработки метода, позволяющего показать информационное окно с картинкой. На мой взгляд, единственным недостатком приведенного метода, является сложность его вызова. Действительно, чтобы  показать достаточно простое окно, нам пришлось создавать экземпляры класса PopubButton, задавать имена и т.д. давайте сегодня посмотрим пример паттерна Фасад, который позволит упростить жизнь тем, кто решит воспользоваться этим классом.

среда, 14 ноября 2012 г.

Как заставить async метод вести себя как синхронный

Недавно, я в гневе писал вот эту статью, про то, что методы помеченные как async ведут себя не так, как от них ожидается. Давайте, сегодня я покажу небольшой пример на то, как вернуть им возможность выполниться как синхронным.

вторник, 16 октября 2012 г.

Про непонимание новомодных штук и к чему это приводит

На работе, уже два дня бегаю по руинам. Почему? А потому, что одному коллеге показалось, что новомодные штуки это круто, а раз круто, то должно быть и у нас. Вот про то, как работающий код был убит новомодными async и await, я и расскажу под катом.

среда, 12 сентября 2012 г.

Синтаксический сахар async и await

Вчера, в разговоре со Стасом, мы что-то начали обсуждать async и await с точки зрения, понимания. Вот пришел новый программист, вот показали ему магию, а как оно работает? А кто же его знает? В этом посте, попробую предложить вариант реализации того же функционала на старых, добрых потоках.

пятница, 1 июня 2012 г.

Часть 6. Многопоточность на примере матричного фильтра - размытие

Итак, для примера многопоточного приложения воспользуемся применением фильтра размытие. Хорошая статья про матричные фильтры есть на хабре. Здесь на алгоритме фильтра я останавливаться не буду, кто захочет, почитает по ссылке или разберется сам по коду. Мы же сегодня посмотрим, как количество потоков влияет на производительность приложения.

пятница, 25 мая 2012 г.

Часть 5. События синхронизации

Предыдущие примеры показывали, как обеспечить «критические секции», но иногда возникает необходимость не заблокировать доступ к некоторым данным из нескольких потоков, а просто уведомить, что часть работы сделана, продолжайте. Вот сегодня давайте и посмотрим, как это можно реализовать.

понедельник, 21 мая 2012 г.

Часть 4. Способы синхронизации потоков в .Net

Итак, мы с вами уже познакомились с двумя способами синхронизации в .Net приложениях. Внимательный читатель спросит, откуда два. Ведь мы смотрели только ключевое слово lock. И будет неправ, т.к. мы еще использовали метод Join, который приостанавливает выполнение текущего потока, до тех пор, пока не завершится поток, для которого и вызван Join. Во многих случаях этот метод удобнее использовать по сравнению с другими способами синхронизации. Теперь же, давайте познакомимся с другими способами, которые предоставляет  нам с вами .Net.

вторник, 15 мая 2012 г.

Часть 3. Гонки и тупики

Итак, мы с вами уже посмотрели, что запустив задачи не последовательно, а параллельно, на компьютере с более чем одним процессором/ядром, мы получаем существенный прирост производительности. Но, к сожалению, помимо плюсов, которые дает распараллеливание, оно дает и существенные минусы. Именно о них мы сегодня и поговорим. Кстати, давайте я не буду больше писать через дробь: процессор/ядро, везде говоря процессор, я буду понимать под ним как процессор, так и ядро, а если разница будет принципиальная, то я об этом скажу отдельно.

суббота, 12 мая 2012 г.

Часть 2. Процессы и потоки

Под процессом в современных операционных системах понимают запущенную программу. Т.к. для каждой запущенной программы ОС выделяет свою область памяти, предоставляет ей отдельный квант процессорного времени, то при помощи процессов можно реализовать параллельную обработку данных.
Давайте решим нашу задачу поиска элемента, но только не в массивах, а в файлах. Применять будем параллелизм задач, т.к. он для процессов его проще применить (у разных процессов нет общей памяти, а передача информации из процесса в процесс достаточно сложна).

пятница, 11 мая 2012 г.

Часть 1. История развития параллельной обработки и классификация современных подходов

В 1946 году трое ученых, одним из которых был Джон фон Нейман, опубликовали статью, в которой изложили 5 принципов заложивших основу современных компьютеров. Два других автора: Артур Бёркс и Герман Голдстайн, и тогда были не очень известны, а т.к. эти принципы, в силу известности фон Неймана, получили название в его честь, то про этих двух авторов сейчас мало кто и знает.
Одним из принципов предложенным в этой статье, был принцип «Последовательного программного управления», который гласит: «Программа состоит из набора команд, которые выполняются процессором автоматически друг за другом в определенной последовательности». И этот постулат, надолго определил основное направление развития процессоров, да и вычислительной техники. И только относительно недавно, когда увеличивать тактовую частоту процессоров стало технологически не выгодно, основные взоры обратились из последовательного выполнения команд, в параллельное.

вторник, 27 марта 2012 г.

Async и await

Иногда ожидание бывает дольше, чем хотелось бы пользователю. И если во время этого ожидания приложение еще и не реагирует на действия пользователя, то он вообще в гневе. Достаточно давно, я уже писал как можно реализовать многопоточное приложение. В Framework 4.5 появилась пара ключевых слов, которые позволяют реализовать еще один механизм выолнения длительной операции в отдельном потоке. Это слова async и await.

четверг, 22 марта 2012 г.

Task-и в C#

В C# 4.5 появились два ключевых слова async и await. Но о них, как нибудь в другой раз. Но вот чтобы они заработали в них применяются Task-и, которые доступны были и раньше. Сегодня я хочу показать простенький пример именно на класс Task.

среда, 23 ноября 2011 г.

О том как в C# применить dynamic

Когда добавляли в C# слово dynamic видимо основное назначение было в интеграции с COM. Но оказалось, что его можно весьма неплохо применить и в других задачах.

понедельник, 23 ноября 2009 г.

Создание окна из потока отличного от потока диспетчера приложения

Возникла задача, в процессе вызова метода из workflow показать форму для ввода дополнительных данных (для тех, кто не в курсе - workflow выполняются в отдельном потоке, и соответственно если метод вызывается из workflow, он тоже выполняется в этом потоке). Приложение написано на WPF. Привычная последовательность действий:
    public void StartReadFromScala(Guid idWorkflow)
    {
      WndReadFromScala form = new WndReadFromScala();
      form.Show();
    }


* This source code was highlighted with Source Code Highlighter.

Выполнялось, но форма не появлялась :(

Пришлось пойти на следующее ухищрение:
    public void StartReadFromScala(Guid idWorkflow)
    {
      // Создаем форму для ввода данных, но создаем ее в главном потоке
      Application.Current.Dispatcher.Invoke(new NoParamHandler(CreateWndReadFromScala), new object[] { });
    }

    private void CreateWndReadFromScala()
    {
      WndReadFromScala form = new WndReadFromScala();
      form.Show();
    }


* This source code was highlighted with Source Code Highlighter.

А вот теперь все работает ;)

вторник, 19 мая 2009 г.

Многопоточный доступ в WPF

Одной из проблем при работе в WPF с визуальными компонентами заключается в том, что доступ к ним из любого потока отличного от их породившего приводит к исключению.

Для примера возьмем простое приложение, со следующим интерфейсом:

При нажатии на кнопку "Старт" запускается длительная операция выводящая состояние процесса в ProgressBar.


Код метода длительной операции для простоты возьмем вот такой:

private int LongOperation()
{
for (int i = 0; i < 100; i++)
{
// Имитация полезной работы
Thread.Sleep(100);
// Сообщаем в визуальную часть, что часть работы выполнена
SetProgressBarValue(i + 1);
}
return 0;
}


* This source code was highlighted with Source Code Highlighter.


Обработчик клика на кнопке:


private void startButton_Click(object sender, RoutedEventArgs e)
{
Func<int> operation = LongOperation;
operation.BeginInvoke(null, null);
}


* This source code was highlighted with Source Code Highlighter.

При попытке реализовать метод SetProgressBarValue в лоб:


private void SetProgressBarValue(int newValue)
{
workProgress.Value++;
}


* This source code was highlighted with Source Code Highlighter.

мы получим InvalidOperationException

Для решения этой проблемы необходимо воспользоваться замечательным классом Dispatcher, переписав с его помощью код, мы получим:


// Делегат для перевызова метода SetProgressBarValue через диспетчер
private delegate void SetProgressBarValueHandler(int newValue);

private void SetProgressBarValue(int newValue)
{
// Проверяем совпадает ли поток диспетчера с потоком вызвавшим метод
if (Dispatcher.Thread == Thread.CurrentThread)
{
// Все замечательно :) меняем значение прогресбара
workProgress.Value = newValue;
}
else
{
// Нет :( все плохо :( перезапускаем метод в потоке диспетчера
Dispatcher.Invoke(new SetProgressBarValueHandler(SetProgressBarValue), new object[] { newValue });
}
}


* This source code was highlighted with Source Code Highlighter.

Вуаля, все заработало :)

Проект можно скачать здесь: MultithreadingWPF.rar