2015-07-08 3 views
0

У меня есть приложение WPF на C#, которое выполняет некоторую обработку данных. Поскольку приложение занимает некоторое время, чтобы выполнить обработку, иногда окно зависает. Поэтому я в основном пытаюсь найти способ, чтобы пользователь не волновался. Я подумывал о создании второго окна, когда обработка происходит с некоторой статистикой, в то время как основное окно остается либо в фоновом режиме, либо скрыто до тех пор, пока обработка не будет завершена в зависимости от того, что работает лучше. Может быть, это предотвратит от замораживания или по крайней мере скрытие этого?Как работать с несколькими окнами в WPF

На данный момент я попытался создать второе окно, когда обработка начинается с использования следующего кода ... но я не уверен, как отредактировать XAML для него. Я использую VS 2013 и вижу только XAML для своего начального окна. Любая помощь будет оценена!

Window win = new Window(); 
    win.Show(); 
    win.Activate(); 
+0

Для простоты, если ваше приложение ничего не делает, кроме обработки данных, у вас нет причин использовать несколько потоков. Как вы уже упоминали, вы можете отобразить всплывающее диалоговое окно с информацией, например «Расчет выполняется ...», когда начинается расчет, и скрыть окно, например, когда произошло событие OnFinished. – Fragment

+0

В хорошо спроектированном приложении может быть только одно окно. – Maximus

ответ

5

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

Настоящим решением проблемы является асинхронное кодирование. Для получения дополнительной информации см. .net TPL, а также функции async/await. Они доступны в .net 4.0 и 4.5 соответственно.

Вот пример того, как вы его используете.

private async void BeginProcessingAsync(Data d) 
{ 
    //Show to user that task is running 
    this.IsLoading = true; // Show a loading icon or something. 

    //Execute the long running task asynchronously 
    await Task.Run(() => LongRunningMethod(d)); 

    //Anything after the await line will be executed only after the task is finished. 
    this.IsLoading = false; 
    DoSomethingWithFinishedData(d); 
} 
+0

Спасибо, это действительно помогло мне. Кроме того, для тех, кто использует это решение. Если ваш проект нацелен на «.NET 4.0», используйте 'Task.Factory.StartNew()' вместо 'Task.Run()'. – sparta93

2

Вы должны запустить свою длительную обработку на другом потоке или в фоновом режиме.

Один простой способ сделать это с BackgroundWorker

var bw = new BackgroundWorker(); 
bw.DoWork += (s, e) => 
    { 
     //put the long running process in here. 
    }; 

bw.RunWorkerAsync(); 
+0

'bw.DoWork + = (s, e) =>' что означает эта часть? – sparta93

+0

, который создает анонимный обработчик событий. 's' является« отправителем »события,' e' является «EventArgs» события, предоставленного 'DoWork'. Вам не нужно использовать ни один из них. – DLeh

+0

Я скопировал ваш код внутри события нажатия кнопки и назвал функцию, которая довольно долго работает внутри нее, ничего не произошло. Он просто пропустил весь фрагмент. Прошло время: 0.00 секунды – sparta93

0

Проблема, с которой вы сталкиваетесь, заключается в том, что у вас есть поток пользовательского интерфейса, пытающийся выполнить всю работу. Хотя поток пользовательского интерфейса работает в долгосрочном режиме, он не может обновить ваше окно.

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

Токен отмены можно использовать с Task class. Вы можете дополнить это с помощью await/async, поэтому вам не нужно вручную проверять, чтобы ждать завершения выполнения задачи.

Ваши варианты будут зависеть от вашей текущей структуры.