2009-05-22 2 views
3

добрый вечер!Как обрабатывать длинные «потоки» в WPF?

В настоящее время я разрабатываю wpf-клиент для некоторого отдыха. общение с сервисом rest-service не является проблемой и выполняется в дополнительной сборке (интерфейс общения).

в основном:
У меня есть как-то «поиск», который выполняет метод. этот метод связывается со службой, обновляет некоторые текстовые поля и панель выполнения (чтобы дать пользователю некоторую графическую информацию, насколько мы ...). К сожалению, сервер, на котором размещена служба, немного хромает, вызывая некоторое серьезное время отклика (около 4 секунд). это, с другой стороны, заставляет мое приложение wpf ждать, а это заканчивается: черным и титлингом «не отвечает» ...

Я уже пытался выполнить это выполнение в другом потоке, но ... логично, что я не получу никакого доступа к элементам управления моего wpf-окна ...

atm я действительно беспомощный ... может ли кто-нибудь дать мне рутинную рутину или решение?

ответ

5

This video показывает, как создать асинхронный индикатор с использованием WPF и метод Dispatcher.BeginInvoke. Это приятное и легкое введение в простое решение для основных проблем с перекрестными потоками в WPF.

+0

диспетчер-вариант - самый приятный ... большое спасибо! –

+1

http://windowsclient.net/learn/video.aspx?v=57027 перенаправляется на https://www.microsoft.com/net. Я что-то упускаю? – VivekDev

+0

Хотелось бы увидеть, что vid, если у кого-то есть обновленная ссылка? – HischT

5

Ваш пользовательский интерфейс занят ожиданием ответа от веб-службы и недоступен для рисования экрана. Один хороший вариант - перенаправить запрос службы на другой поток, отличный от UI. Посмотрите на BackgroundWorker, который был разработан специально, чтобы сделать это легко. Он обрабатывает перекрестные вызовы перекрестных потоков от не-UI к потокам пользовательского интерфейса.

Грубо:

BackgroundWorker bw = new BackgroundWorker(); 
bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); 
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 
bw.RunWorkerAsync(arg); 
... 

static void bw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    BackgroundWorker worker = (BackgroundWorker)sender; 
    int arg = (int)e.Argument; 
    e.Result = CallWebService(arg, e); 
} 

static void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    progressBar.Increment(); 
} 

static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    label.Text = "Done: " + e.Result.ToString(); 
} 
+0

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

+1

Код? Кроме того, убедитесь, что вы * не * касаетесь вашего пользовательского интерфейса от обработчика событий DoWork. –

+0

... или что-либо, вызываемое им (выполняется на одном и том же потоке, отличном от UI). –

1

Чтобы получить доступ к управлению от второго использования нити Dispatcher.BeginInvoke:

Dispatcher.BeginInvoke(new Action(() => 
    { 
     // Update your controls here. 
    }), null); 

Или вы можете посмотреть в использовании BackgroundWorker.

Смежные вопросы