web-dev-qa-db-fra.com

Fichier de téléchargement de l'API Web 2 à l'aide de la tâche asynchrone <IHttpActionResult>

J'ai besoin d'écrire une méthode comme ci-dessous pour retourner un document texte (.txt, pdf, .doc, .docx etc.) Bien qu'il existe de bons exemples de publication de fichier dans Web API 2.0 sur le Web, je n'ai pas trouvé de document pertinent pour juste en télécharger un. (Je sais comment le faire dans HttpResponseMessage.)

  public async Task<IHttpActionResult> GetFileAsync(int FileId)
  {    
       //just returning file part (no other logic needed)
  }

Est-ce que ce qui précède doit être asynchrone? Je cherche uniquement à retourner le flux. (Est-ce OK?)

Plus important encore avant de finir le travail dans un sens ou dans l'autre, je voulais savoir quelle était la "bonne" façon de faire ce genre de travail ... (donc les approches et les techniques le mentionnant seraient grandement apprécié) .. merci.

20
Kcats Wolfrevo

À droite, pour votre scénario ci-dessus, l'action n'a pas besoin de renvoyer un résultat d'action async. Ici, je crée un IHttpActionResult personnalisé. Vous pouvez consulter mes commentaires dans le code ci-dessous ici.

public IHttpActionResult GetFileAsync(int fileId)
{
    // NOTE: If there was any other 'async' stuff here, then you would need to return
    // a Task<IHttpActionResult>, but for this simple case you need not.

    return new FileActionResult(fileId);
}

public class FileActionResult : IHttpActionResult
{
    public FileActionResult(int fileId)
    {
        this.FileId = fileId;
    }

    public int FileId { get; private set; }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        HttpResponseMessage response = new HttpResponseMessage();
        response.Content = new StreamContent(File.OpenRead(@"<base path>" + FileId));
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");

        // NOTE: Here I am just setting the result on the Task and not really doing any async stuff. 
        // But let's say you do stuff like contacting a File hosting service to get the file, then you would do 'async' stuff here.

        return Task.FromResult(response);
    }
}
37
Kiran Challa

Les méthodes sont asynchrones si elles retournent un objet Task, et non parce qu'elles sont décorées avec un mot clé async. async n'est qu'un sucre syntaxique pour remplacer cette syntaxe ce qui peut devenir assez complexe lorsqu'il y a plus de tâches combinées ou plus de continuations:

public Task<int> ExampleMethodAsync()
{
    var httpClient = new HttpClient();

    var task = httpClient.GetStringAsync("http://msdn.Microsoft.com")
        .ContinueWith(previousTask =>
        {
            ResultsTextBox.Text += "Preparing to finish ExampleMethodAsync.\n";

            int exampleInt = previousTask.Result.Length;

            return exampleInt;
        });

    return task;
}

Échantillon d'origine avec async: http://msdn.Microsoft.com/en-us/library/hh156513.aspx

async nécessite toujours l'attente, ceci est appliqué par le compilateur.

Les deux implémentations sont asynchrone, la seule différence est que async + wait remplace remplace le ContinueWith en code "synchrone".

Renvoyer la tâche à partir des méthodes du contrôleur qu'est-ce que IO (99% des cas que j'estime) est important parce que le runtime peut suspendre et réutiliser le thread de requête pour servir d'autres requêtes tandis que le IO l'opération est en cours. Cela réduit les chances de manquer de threads de pool de threads. Voici un article sur le sujet: http://www.asp.net/mvc/overview/performance/using-asynchronous -méthodes-dans-aspnet-mvc-4

Donc, la réponse à votre question "Est-ce que ce qui précède doit être asynchrone? Je ne cherche qu'à renvoyer le flux. (Est-ce que ça va?)" Est que cela ne fait aucune différence pour l'appelant, cela ne change que l'apparence de votre code ( mais pas comment cela fonctionne).

3
user3285954