Задача <> не содержит определения для 'GetAwaiter'
Client
iGame Channel = new ChannelFactory<iGame> ( new BasicHttpBinding ( BasicHttpSecurityMode . None ) , new EndpointAddress ( new Uri ( "http://localhost:58597/Game.svc" ) ) ) . CreateChannel ( );
public Task<SerializableDynamicObject> Client ( SerializableDynamicObject Packet )
{
return Task<SerializableDynamicObject> . Factory . FromAsync ( Channel . BeginConnection , Channel . EndConnection , Packet , null );
}
Договор
[OperationContract ( AsyncPattern = true )]
IAsyncResult BeginConnection ( SerializableDynamicObject Message , AsyncCallback Callback , object State );
SerializableDynamicObject EndConnection ( IAsyncResult Result );
Сервис
public IAsyncResult BeginConnection ( SerializableDynamicObject Message , AsyncCallback Callback , object State )
{
dynamic Request = Message;
dynamic Response = new SerializableDynamicObject ( );
if ( Request . Operation = "test" )
{
Response . Status = true;
}
Response . Status = false;
return new CompletedAsyncResult<SerializableDynamicObject> ( Response );
}
public SerializableDynamicObject EndConnection ( IAsyncResult Result )
{
return ( Result as CompletedAsyncResult<SerializableDynamicObject> ) . Data;
}
Предоставление услуг от клиента Silverlight
private async void myButton ( object sender , RoutedEventArgs e )
{
dynamic Request = new SerializableDynamicObject ( );
Request . Operation = "test";
var task = Client ( Request );
var result = await task; // <------------------------------ Exception
}
Исключение
Task<SerializableDynamicObject > does not contain a definition for 'GetAwaiter'
Что неправильно?
Изменить 1:
Вкратце,
Visual studio 2012 RC Приложение Silverlight 5 потребляет Game WCF 4 Service, размещенное в приложении ASP.net 4 с технологией ChannelFactory через Shared Portable Library.NET4/SL5 содержит интерфейс iGame с Async CTP
График:
ASP.NET < = Библиотека классов (игра) < = Портативная библиотека (iGame) = > Silverlight
Изменить 2:
- В моем SL5-клиенте добавлен Microsoft.CompilerServices.AsyncTargetingPack.Silverlight5.dll
- используя Систему. Потоки. Задачи;
Ответы
Ответ 1
GetAwaiter()
, который используется await
, реализован как метод расширения в Async CTP. Я не уверен, что именно вы используете (вы упомянули в своем вопросе как Async CTP, так и VS 2012 RC), но возможно, что пакет таргетинга Async использует ту же технику.
Проблема в том, что методы расширения не работают с dynamic
. Что вы можете сделать, это явно указать, что вы работаете с Task
, что означает, что метод расширения будет работать, и затем переключиться обратно на dynamic
:
private async void MyButtonClick(object sender, RoutedEventArgs e)
{
dynamic request = new SerializableDynamicObject();
request.Operation = "test";
Task<SerializableDynamicObject> task = Client(request);
dynamic result = await task;
// use result here
}
Или, поскольку метод Client()
на самом деле не является динамическим, вы можете вызвать его с помощью SerializableDynamicObject
, а не dynamic
, и, таким образом, ограничить использование dynamic
в максимально возможной степени:
private async void MyButtonClick(object sender, RoutedEventArgs e)
{
var request = new SerializableDynamicObject();
dynamic dynamicRequest = request;
dynamicRequest.Operation = "test";
var task = Client(request);
dynamic result = await task;
// use result here
}
Ответ 2
У меня была эта проблема в одном из моих проектов, где я обнаружил, что для моего проекта .Net Framework установлена версия 4.0, и асинхронные задачи поддерживаются только в .Net Framework 4.5 и более поздних версиях.
Я просто изменил настройки своего проекта, чтобы использовать .Net Framework 4.5 или выше, и это сработало.
Ответ 3
Вам нужно установить Microsoft.Bcl.Async Пакет NuGet, который сможет использовать конструкции async/await
в версиях pre -.NET 4.5 (например, Silverlight 4.0 +)
Просто для ясности - этот пакет назывался Microsoft.CompilerServices.AsyncTargetingPack
, а некоторые старые учебники по-прежнему относятся к нему.
Посмотрите здесь для информации от Immo Landwerth.
Ответ 4
Просто испытал это в методе, который выполняет запрос linq.
public async Task<Foo> GetSomething()
{
return await (from foo in Foos
select foo).FirstOrDefault();
}
Необходимо использовать .FirstOrDefaultAsync()
. Ошибка N00b.
Ответ 5
Вы все еще можете использовать framework 4.0, но вы должны включить getawaiter
для классов:
MethodName(parameters).ConfigureAwait(false).GetAwaiter().GetResult();
Ответ 6
У меня была эта проблема, потому что я вызывал метод
await myClass.myStaticMethod(myString);
но я установил myString с
var myString = String.Format({some dynamic-type values})
что привело к типу dynamic
, а не a string
, поэтому, когда я попытался ждать на myClass.myStaticMethod(myString)
, компилятор думал, что я намеревался позвонить myClass.myStaticMethod(dynamic myString)
. Это скомпилировано отлично, потому что, опять же, в динамическом контексте, все это хорошо, пока он не взорвется во время выполнения, что и произошло, потому что нет реализации динамической версии myStaticMethod
, и это сообщение об ошибке не помогло и тот факт, что Intellisense подведет меня к правильному определению, тоже не помогло.
Tricky!
Однако, заставив тип результата в строку, например:
var myString = String.Format({some dynamic-type values})
to
string myString = String.Format({some dynamic-type values})
мой вызов myStaticMethod
правильно маршрутизирован
Ответ 7
В моем случае просто добавьте using System;
решить вопрос.
Ответ 8
Убедитесь, что ваш .NET версии 4.5 или выше
Ответ 9
public async Task<model> GetSomething(int id)
{
return await context.model.FindAsync(id);
}