Страницы

Поиск по вопросам

вторник, 28 января 2020 г.

Как правильно выполнить метод в отдельном потоке?

#c_sharp #wpf #потоки_данных #многопоточность


Не могу сообразить как же все-таки вытащить метод в отдельный поток. Прошу помощи
в разжевывании информации о работе с потоками.
Есть момент когда в приложении открывается внешний файл достаточно большого размера,
и в этот момент выполняется анимация. Ну так вот, анимация, как и все приложение виснет
на этот момент (ну это само собой...) Нужно чтобы анимация так и продолжала работать,
без рывков и тормозов, пока в отдельном потоке открывается файл.
.NET 4 (выше нельзя)
студия 2012, если нужно могу скинуть проект...    


Ответы

Ответ 1



Для начала, структурируйте вашу программу. Часть, которая занимается представлением (View), должна быть отделена от управляющей части (ViewModel), и от различных движков (Model). Когда ViewModel решает, что нужно открыть файл, запрос на открытие и разбор содержимого должен уйти в движок разбора файла и построения объектной модели. Модель сама по себе вполне может быть однопоточной, а вот бизнес-логика пусть занимается перебрасыванием информации между потоками. Итак, на уровне модели ваш код прост и линеен: public Document ReadFromFilename(string filename) { using (var fs = new FileStream(filename, FileMode.Open)) return ReadFromStream(fs); } protected Document ReadFromStream(IStream stream) { ... На уровне VM вам нужно немного больше: public void async OpenDocumentAsync(string filename) { try { // установить статус ожидания this.ReadStatus = ReadStatus.Reading; // распарсить документ var doc = await DocumentHelper.GetDocumentAsync(filename); // создать VM-структуру var vmDoc = new VM.Document(doc); // установить текущую страницу и создать соответствующие подструктуры await vmDoc.SwitchToPageAsync(0); // доложить, что всё в порядке this.ReadStatus = ReadStatus.Ready; // не забыть обновить свойство DataContext'а this.Document = vmDoc; } catch (<что нужно>) { // доложить, что что-то пошло не так this.ReadStatus = ReadStatus.Failed; } } Метод DocumentHelper.GetDocumentAsync будет выглядеть как-то так: public Task GetDocumentAsync(string filename) { var t = new Task(() => model.ReadFromFilename(filename)); t.Start(taskSchedulers[model]); return t; }

Ответ 2



new Thread(() => MyMethod()).Start(); Метод в отдельном потоке... В чем проблема-то? С данными: int i = 0; new Thread(() => { MessageBox.Show(i.ToString()); }).Start(); Если .Net Framework 4 или выше, то ниже Вам написали пример. Также, что касается примера ниже, читайте про async/await

Ответ 3



На выбор: Task.Run(()=> /*code*/); Task.Factory.StartNew(Method, params);

Ответ 4



Здесь я описывал два способа взаимодействия GUI с рабочими потоками.

Комментариев нет:

Отправить комментарий