2016-12-20 4 views
-3

У меня есть интерфейс:Получение двойной задачи вместо задачи в C# Задача, почему?

public interface IService 
{ 
    Task<double> GetData(int id); 
} 

И мне нужно использовать этот интерфейс в моем классе:

//_svc is a Type of IService 

public async void Doit() 
{ 
    Task<double> task = await _svc.GetData(id); 
} 

И когда я это делаю, это говорит, что он не может преобразовать тип двойной в Задача < double>
Почему этот двойной вместо задачи? Интерфейс четко указывает, что это задача, и здесь мне нужно получить задачу, а не значение.

+0

это потому, что Task возврат двойной. GetData получит данные в фоновом режиме и вернется к основному потоку в качестве dobule – Sasha

+2

Подробнее о 'await' ключевое слово – Backs

+0

Может быть, я должен изменить способ, которым я его называю? Задача t = Задача. Run (() => _svc.GetData (id)); ? –

ответ

4

Если вам нужно выполнить задачу самостоятельно, удалите await, который обрабатывает ее для вас.

+0

Вы имеете в виду, я использую: Задача task = _svc.GetData (id); –

+0

Нет Задание. Нужен? –

+0

'Task.Run', вероятно, находится внутри метода, возвращающего задачу. – nvoigt

1

Это не ответ, но я надеюсь, что это поможет вам понять Задачи немного больше. Например у вас есть интерфейс с методом:

System.Threading.Tasks.Task<string> FindNameAsync(string computerName); 

При вызове метода из интерфейса, то это будет что-то вроде этого:

var result = await _scv.FindNameAsync(name); //The program will not go to next line, until it becomes result 

Когда это будет получить результат будет идти дальше. И в результате вы можете перейти к следующему методов

EDIT Если вы хотите, чтобы получить статусы вы можете сделать небольшие изменения:

System.Threading.Tasks.Task<bool> FindNameAsync(string computerName); 

Затем вы можете вернуться верно в случае успеха, в другом случае - ложь , С небольшой модификацией вы можете передать объект методу в качестве параметра и сохранить значения, которые вам нужны. Или вы можете вернуть словарь или турп, а не bool. Маленький пример: Ваш метод может быть как здесь:

System.Threading.Tasks.Task<bool> FindNameAsync(SomeClass obj); 

И вы можете справиться с этим так:

SomeClass test = new SomeClass(); 
if(await _scv.FindNameAsync(test)) 
{ 
//code for success result 
}else 
{ 
//if error happened handle here 
} 
+0

Это не то, что мне нужно. Мне нужно обработать статусы задачи. Поэтому мне нужно вызвать метод в задаче и проверить состояния и только затем получить результат с continueWith –

+2

@ J.Doe: вам не нужно это делать. Вы должны *** никогда не использовать 'ContinueWith'. –

0

интерфейс четко указывает, что это задача, и здесь мне нужно, чтобы получить а не значение.

Когда интерфейс объявляет метод, который возвращает Task или Задача <T> имя метода должно - по соглашению - также заканчиваться «Async»: https://msdn.microsoft.com/en-us/library/hh191443

Такой метод, как ожидается, будет реализован как метод асинхронной, который возвращает объект типа T, если возвращаемый тип объявлен как Task <T> или вообще ничего, если возвращаемый тип просто Задача:

public interface IService 
{ 
    Task<double> GetDataAsync(int id); 
} 

public class Service : IService 
{ 
    public async Task<double> GetDataAsync(int id) 
    { 
     await Task.Delay(1000); 
     return 1.0; 
    } 
} 

Вы бы ждать су ч метод:

public class Consumer 
{ 
    public async void Doit() 
    { 
     IService service = new Service(); 
     double d = await service.GetDataAsync(1); 
    } 
} 

Теперь метод фактически является реализован ли как метод асинхронной является деталью реализации в конкретной реализации интерфейса, но это действительно не имеет значения, насколько потребитель интерфейса что вы все еще можете ожидать метода, который возвращает задачу или задачу (при условии, что метод вызывающего абонента, по-видимому, помечен ключевым словом async).

Вы бы, например, быть в состоянии ждать следующую реализации без асинхронной методы точно так же:

public class Service : IService 
{ 
    public Task<double> GetDataAsync(int id) 
    { 
     return Task.FromResult(1.0); 
    } 
} 

Так методов, которые имеют тип возврата задачи или задачи <T> предназначены для асинхронный и ожидаемый.

Вы могли еще хранить экземпляр фактического типа возвращаемого значения метода в переменной «как обычно», хотя:

public void Doit() 
    { 
     IService service = new Service(); 
     Task<double> task = service.GetDataAsync(1); 
    } 

Это, однако, просто вызвать асинхронно, не дожидаясь его возвращаемого значения, что делает его довольно бесполезно даже назвать метод в первую очередь. При вызове асинхронного метода аранжировки и условного соглашения, который возвращает задачу <double>, вы заинтересованы в получении двойного значения обратно asynchronously. Вы действительно не заботитесь о самом объекте Task, если понимаете, что я имею в виду.

+1

'Вы бы назвали такой метод async, ожидая его:' Нет, вы не * вызываете * метод, ожидая его. Вы вызываете его, вызывая его, 'service.GetDataAsync (1)'. Вы продолжаете выполнение метода, когда 'Task' завершается, ожидая его. Большая разница. – Servy

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