#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 TaskGetDocumentAsync(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 с рабочими потоками.
Комментариев нет:
Отправить комментарий