2014-06-12 3 views
1

Так что я просто хочу сделать свой сервисный уровень async.ASP NET MVC 5 Task Async Создайте метод Async

У меня есть новая услуга ProjectManagement, и я хочу, чтобы ее метод GetProjects был асинхронным.

public Task<string> GetProjectsAsync() 
{ 
    var json = JsonConvert.SerializeObject(_repository.All<Projects>()); 

    return json; 
} 

Я знаю, что этот метод не работает, очевидно, потому, что я вернуть строку, а не Task<string>. Итак, как мне использовать Task.Run() для запуска этого метода и возврата результата?

Я посмотрел на это documentation, и я немного смущен о том, как его использовать?

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

var jsonData = await _projectManagement.GetProjectsAsync(); 
+2

Единственная настоящая причина делает метод асинхронным, если вы действительно можете выполнить IO асинхронно. Если вы не можете, вы можете просто оставить его синхронным методом. – Servy

+0

Возврат строки при возврате типа метода 'Task ' является правильным поведением. Просто поместите async перед методом 'GetProjectsAsync()'. – Abhijeet

+3

@Abhijeet Это ужасная идея. Это создает синхронный метод и просто завершает его результат в задачу, по существу делая утверждение, что это асинхронная ложь. Вы не должны этого делать. Если вы не хотите, чтобы метод был асинхронным, вы не должны лгать своим абонентам и утверждать, что вы асинхронны. – Servy

ответ

5

При преобразовании в async, вы хотите, чтобы начать на «листьях «и работайте над своими контроллерами/пользовательским интерфейсом. Я сделал много конверсий, и это лучший подход, который я нашел.

Итак, сначала определите любые операции, которые являются естественно асинхронными; любая привязка I/O - хорошая ставка. Вы уже определили один: вызов базы данных.

Далее, начните с кода нижнего уровня и сделайте это асинхронным. Здесь возникает ваша проблема; вы думаете о форсировании асинхронности посередине, используя Task.Run, но вам нужно погрузиться глубже на более низкий уровень и сделать его асинхронным до конца.

К примеру, я буду считать, что ваш репозиторий с помощью Entity Framework, и что ваш метод All<T> выглядит примерно так:

public List<T> All<T>() 
{ 
    return _context.Set<T>().ToList(); 
} 

Тогда вы бы начать с создания асинхронного версию этого репозитория метода:

public Task<List<T>> AllAsync<T>() 
{ 
    return _context.Set<T>().ToListAsync(); 
} 

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

public string GetProjects() 
{ 
    var json = JsonConvert.SerializeObject(_repository.All<Projects>()); 
    return json; 
} 

становится этим:

public async Task<string> GetProjectsAsync() 
{ 
    var json = JsonConvert.SerializeObject(await _repository.AllAsync<Projects>()); 
    return json; 
} 

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

+0

Я не могу реализовать метод 'AllAsync', потому что он говорит:« Невозможно неявно преобразовать список в задачу » –

+0

Посмотрите еще раз на код. Это 'ToListAsync', а не' ToList'. –

+0

Да, я сделал это :) –

-3

вы должны попробовать эту ссылку http://www.dotnetperls.com/async

private async void DoAsyncWork() 
{ 
    var data = await GetProjectAsync(); 
} 

async Task<string> GetProjectAsynce() 
{ 
    // code to get stuff done 
    // await key word may be needed depending on 
    // what you are doinf 
    return JsonConvert.SerializeObject(myRepository.All<Projects>()); 
    // convert to string first of course 
}