Есть ли эффективный способ использования System.Threading.Tasks с прокси-серверами службы WCF?

После прочтения последней статьи журнала MSDN Magazine о планировщике задач я надеялся, (и на самом деле очень взволнован), что его использование принесет пользу моему использованию прокси-серверов, созданных WCF.

Я надеялся получить некоторые из следующих преимуществ:

  • 1) Возможность прервать выполняемую операцию WCF (я не ожидаю, что это остановит операцию на сервере — я просто хотел бы иметь возможность сигнализировать, что "мне не нужен результат для этой задачи". Это особенно часто встречается в пользовательском интерфейсе, когда кто-то неоднократно выбирает элементы из сетки, которые вызывают вызовы службы.)
  • 2) Возможность запустить задачу в любой момент, кроме момента ее создания. Я не уверен, что мне это действительно нужно, я просто подумал, что было бы неплохо сгенерировать задачу, а не сразу запускать ее. В конце концов, я думал, что в этом весь смысл задач.
  • 3) Привязываемые свойства — поэтому я могу привязать свой пользовательский интерфейс WCF к IsCompleted и позволить классу Task абстрагироваться от внутренних компонентов операции из моего пользовательского интерфейса.
  • 4) Возможность абстрагироваться от выполнения операции — насмешки, бла-бла-бла, будущий рефакторинг и т. д.

Однако - я, кажется, не получаю НИКАКИХ из этих преимуществ.

  • 1) В Task нет функции прерывания, что кажется мне очень странным.
  • 2) Единственная перегрузка, которую я смог заставить работать с Task.Factory.FromAsync<>, показана ниже. Это немедленно начинает выполнение операции веб-службы (как показано в Fiddler) и не позволяет мне начать вызов позже.
  • 3) Задача не реализует INotifyPropertyChanged, поэтому я не могу привязать ее к пользовательскому интерфейсу.
  • 4) Это вроде как мертво в воде, учитывая, что остальные 3 преимущества не происходят :-(

Sooo .... Я просто трачу свое время, пытаясь заставить сгенерированные WCF прокси-серверы работать с задачами - или я что-то упустил.

// WCF client
var client = new ShoppingCartClient();

// create task
var t = Task.Factory.FromAsync<GetOrderDetailsMsgOut>(
              client.BeginGetOrderDetails(new GetOrderDetailsMsgIn()
              {
                  OrderId = 12345
              },  null, null),    
              client.EndGetOrderDetails);

t.ContinueWith(x =>
{
    var order = x.Result.Order;
    // do something with order
}); 

person Simon_Weaver    schedule 13.09.2010    source источник
comment
В чем вы видите разницу между функцией «Прервать», которую вы ищете, и функцией «Отмена», присутствующей в задаче?   -  person John Saunders    schedule 13.09.2010
comment
@john - точно так же, но метода Cancel() тоже нет. есть метод IsCancelled, но нет Cancel(). хотя теперь я вижу, что могу отменить, используя токен отмены msdn.microsoft.com/ en-us/library/dd997364.aspx   -  person Simon_Weaver    schedule 13.09.2010
comment
CancellationToken — это способ отмены.   -  person John Saunders    schedule 13.09.2010
comment
@john - но при выполнении FromAsync я не могу его указать. если я не создам задачу как действие, но тогда есть проблемы с пулом потоков, о которых нужно беспокоиться   -  person Simon_Weaver    schedule 13.09.2010


Ответы (1)


В рамках новых возможностей Async, которые Microsoft планирует использовать в следующей версии C#, они выпустили CTP здесь, он совместим с VS 2010 SP1.

Некоторое время назад я написал небольшой пост в блоге об одном из образцов, поставляемых в комплекте с CTP, о TaskWsdlImportExtension.

person larsw    schedule 28.04.2011