2016-04-07 4 views
0

Мне нужно создать два метода для задачи, каждый из них будет похож на ContinueWith(), но будет выполнять отрисовку в основном потоке пользовательского интерфейса.Действие <Task> реализация

метод перегрузки с параметрами Action, Action<Task>

Метод возвращает Task (для перегрузки с действиями). Возвращенная задача должна завершиться только после завершения основной задачи и продолжения .

Правильно ли он выполняет функцию с Action? А как реализовать второй случай с Action<Task> input с Returned task must finish only after main Task and continuation

Я реализовал

namespace WpfApplication2 
{ 
/// <summary> 
/// Interaction logic for MainWindow.xaml 
/// </summary> 
public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 
     WorkAsync WA = new WorkAsync(); 
     Action firstaction = new Action(WA.Count); 
     WA.Work(firstaction, uiScheduler); 

     Action<Task> secondaction = new Action<Task>(); //What should be here? 
     WA.Work(secondaction, uiScheduler); 
    } 
    public class WorkAsync 
    { 
     public Task Work(Action input, TaskScheduler uiSchedule) 
     { 
      return Task.Factory.StartNew(input).ContinueWith((e) => { Console.WriteLine("Done"); }, uiSchedule); 
     } 
     public Task Work(Action<Task> input, TaskScheduler uiSchedule) 
     { 
      /// What should be here? 
     } 

     public void Count() 
     { 
      for (int i = 0; i < 10; i++) 
      { 
       System.Threading.Thread.Sleep(1000); 
       Console.WriteLine(i); 
      } 
     } 
    } 
} 

}

+0

Похоже, что '' '' '' '' '' '' '' '' '' '' '' '' '' '' де? –

+0

Я думаю, что у вас есть неправильная подпись для второго метода - 'public Task Work (Action input, TaskScheduler uiSchedule)' - мне кажется, что это должно быть 'public Task Work (Task current, Action input, TaskScheduler uiSchedule)' , В противном случае появляется, что вы делаете какую-то невозможную рекурсивную задачу. – Enigmativity

+0

@AlexeiLevenkov, задача выполнить с действием . – A191919

ответ

3

Ваши требования не звучат правильно.

Асинхронный аналог Action не является Action<Task> - это Func<Task>. Существует целый ряд методов, поддерживающих мой вышеприведенный оператор, Task.Run, являющийся одним из них.

Аналогичным образом, для Action<T> асинхронная версия Func<T, Task>. Для Action<T1, T2> это Func<T1, T2, Task>. Вы поняли эту идею.

Таким образом, с учетом этого ваша реализация становится теперь:

public Task Work(Func<Task> input, TaskScheduler uiScheduler) 
{ 
    return input().ContinueWith(e => Console.WriteLine("Done"), uiScheduler); 
} 

Что позволит звонки, как это:

Task myCustomTaskFollowedByConsoleWriteLine = Work(async() => 
{ 
    object result = await SomeIOWorkAsync(); 

    SomeSynchronousCpuBoundWork(result); 
}, 
uiScheduler); 

Вы можете теперь даже выразить другой метод с точки зрения Work(Func<Task>, TaskScheduler):

public Task Work(Action input, TaskScheduler uiScheduler) 
{ 
    return Work(() => Task.Run(input), uiScheduler); 
}