[WPF] Асинхронное выполнение команды
От: Аноним  
Дата: 28.03.11 17:22
Оценка:
Есть обертка над командами, вида

public class Command : ICommand
{
   public Action execute;


   public void Execute()
   {
      if ( execute != null )
          execute();
   }

}


Хотелось бы сделать execute() асинхронным, попробовал сделать так

public void Execute()
{
   if ( execute != null )
    {
       var task = new Task( execute );
       task.Start();
    }
}


Но возникла ошибка , в которой сообщается что визуальные контролы должны инициализироваться в STA потоке. Как это можно обойти ? в execute используется обращение к БД, динамическое создание окна.
Re: [WPF] Асинхронное выполнение команды
От: vit_as Россия  
Дата: 28.03.11 17:28
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть обертка над командами, вида


А>
А>public class Command : ICommand
А>{
А>   public Action execute;


А>   public void Execute()
А>   {
А>      if ( execute != null )
А>          execute();
А>   }

А>}
А>


А>Хотелось бы сделать execute() асинхронным, попробовал сделать так


А>
А>public void Execute()
А>{
А>   if ( execute != null )
А>    {
А>       var task = new Task( execute );
А>       task.Start();
А>    }
А>}
А>


А>Но возникла ошибка , в которой сообщается что визуальные контролы должны инициализироваться в STA потоке. Как это можно обойти ? в execute используется обращение к БД, динамическое создание окна.


Dispathcer.BeginInvoke
Re[2]: [WPF] Асинхронное выполнение команды
От: Аноним  
Дата: 29.03.11 19:08
Оценка:
Здравствуйте, vit_as, Вы писали:

_>Здравствуйте, Аноним, Вы писали:


А>>Есть обертка над командами, вида


А>>
А>>public class Command : ICommand
А>>{
А>>   public Action execute;


А>>   public void Execute()
А>>   {
А>>      if ( execute != null )
А>>          execute();
А>>   }

А>>}
А>>


А>>Хотелось бы сделать execute() асинхронным, попробовал сделать так


А>>
А>>public void Execute()
А>>{
А>>   if ( execute != null )
А>>    {
А>>       var task = new Task( execute );
А>>       task.Start();
А>>    }
А>>}
А>>


А>>Но возникла ошибка , в которой сообщается что визуальные контролы должны инициализироваться в STA потоке. Как это можно обойти ? в execute используется обращение к БД, динамическое создание окна.


_>Dispathcer.BeginInvoke



Спасибо, но получилось не совсем то что нужно.

Вот пример

XAML
<StackPanel>
   <Button Content="Async Call" Click="ButtonClick" />
   <Button Content="Test Click" />
</StackPanel>


public void DoSomeWork()
{
   System.Threading.Thread.Sleep( 15000 );
   var window = new Window();
   System.Threading.Thread.Sleep( 5000 );
   window.Show();
}


public void ButtonClick( object sender, EventArgs e )
{
    Dispatcher.BeginInvoke( new Action( DoSomeWork ) );
}


Так интерфейс зависает , после нажатия на кнопку 20 секунд ничего нельзя нажать.

Посмотрел в документации пример еще один, сделал как там, но в этом случае кидает исключение что поток не тот.
Если в DoSomeWorkAsync использовать Dispatcher оригинальный то получается тот же зависон на 20 секунд.


public static void DoSomeWork()
{
   System.Threading.Thread.Sleep( 15000 );
   var window = new Window();
   System.Threading.Thread.Sleep( 5000 );
   window.Show();
}


public static void DoSomeWorkAsync()
{
    Dispatcher.BeginInvoke( new Action( DoSomeWork ) );
}


public void ButtonClick( object sender, EventArgs e )
{
    new Action( DoSomeWorkAsync ).BeginInvoke( null, null );

}
Re[3]: [WPF] Асинхронное выполнение команды
От: DmitryMS  
Дата: 30.03.11 08:23
Оценка:
В бегин инвоук передается DispatcherPriority.Background. Вроде как, сейчас стало модным делать все на BackgroundWorker'ах.
Re[4]: [WPF] Асинхронное выполнение команды
От: Аноним  
Дата: 30.03.11 15:21
Оценка:
Здравствуйте, DmitryMS, Вы писали:

DMS>В бегин инвоук передается DispatcherPriority.Background. Вроде как, сейчас стало модным делать все на BackgroundWorker'ах.


Background не помогает, он дает только возможность отрисоваться кнопке после нажатия.
Разница между Normal только в том что кнопка перерисовывается как не нажатая, в остальном интерфейс зависает точно также.
Re[3]: [WPF] Асинхронное выполнение команды
От: Codechanger Россия  
Дата: 30.03.11 17:44
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Так интерфейс зависает , после нажатия на кнопку 20 секунд ничего нельзя нажать.


А>Посмотрел в документации пример еще один, сделал как там, но в этом случае кидает исключение что поток не тот.

А>Если в DoSomeWorkAsync использовать Dispatcher оригинальный то получается тот же зависон на 20 секунд.

Еще бы он не зависал... Вы в очередь диспетчера добавили синхронный метод, который спит 20 секунд. В принципе логично, что UI
виснет.
Re[4]: [WPF] Асинхронное выполнение команды
От: Аноним  
Дата: 30.03.11 18:04
Оценка:
Здравствуйте, Codechanger, Вы писали:

C>Здравствуйте, Аноним, Вы писали:



А>>Так интерфейс зависает , после нажатия на кнопку 20 секунд ничего нельзя нажать.


А>>Посмотрел в документации пример еще один, сделал как там, но в этом случае кидает исключение что поток не тот.

А>>Если в DoSomeWorkAsync использовать Dispatcher оригинальный то получается тот же зависон на 20 секунд.

C>Еще бы он не зависал... Вы в очередь диспетчера добавили синхронный метод, который спит 20 секунд. В принципе логично, что UI

C>виснет.

А как добавить асинхронный метод ? Если его сделать в другом потоке то начинаются проблемы с UI, который требует создавать его в потоке STA.
Re[5]: [WPF] Асинхронное выполнение команды
От: JuniorCSharper  
Дата: 30.03.11 18:27
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Codechanger, Вы писали:


C>>Здравствуйте, Аноним, Вы писали:


А>А как добавить асинхронный метод ? Если его сделать в другом потоке то начинаются проблемы с UI, который требует создавать его в потоке STA.


Продумайте архитектуру приложения и отделите UI от расчетных задач. Из расчетных задач кидайте в поток UI события при необходимости что-то отрисовать, заранее подготовленные данные.

Ну, и в порядке бреда, завести еще один поток со своим обработчиком событий и своими элементами UI, обслуживающимися в данном потоке.

Junior
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.