56

I have an API for a system written using the ASP.NET Web Api and am trying to extend it to allow images to be uploaded. I have done some googling and found how the recommended way to accept files using MultpartMemoryStreamProvider and some async methods but my await on the ReadAsMultipartAsync never returns.

Here is the code:

[HttpPost]
public async Task<HttpResponseMessage> LowResImage(int id)
{
    if (!Request.Content.IsMimeMultipartContent())
    {
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    }

    var provider = new MultipartMemoryStreamProvider();

    try
    {
        await Request.Content.ReadAsMultipartAsync(provider);

        foreach (var item in provider.Contents)
        {
            if (item.Headers.ContentDisposition.FileName != null)
            {

            }
        }

        return Request.CreateResponse(HttpStatusCode.OK);
    }
    catch (System.Exception e)
    {
        return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
    }
}

I can step through all the way to:

await Request.Content.ReadAsMultipartAsync(provider);

at which point it will never complete.

What is the reason why my await never returns?

Update

I am attempting to POST to this action using curl, the command is as follows:

C:\cURL>curl -i -F filedata=@C:\LowResExample.jpg http://localhost:8000/Api/Photos/89/LowResImage

I have also tried using the following html to POST to the action as well and the same thing happens:

<form method="POST" action="http://localhost:8000/Api/Photos/89/LowResImage" enctype="multipart/form-data">
    <input type="file" name="fileupload"/>
    <input type="submit" name="submit"/>
</form>
4

5 に答える 5

100

.NET 4.0で似たようなものに遭遇しました(非同期/待機なし)。デバッガーのスレッドスタックを使用すると、ReadAsMultipartAsyncが同じスレッドでタスクを起動していたため、デッドロックが発生したことがわかりました。私はこのようなことをしました:

IEnumerable<HttpContent> parts = null;
Task.Factory
    .StartNew(() => parts = Request.Content.ReadAsMultipartAsync().Result.Contents,
        CancellationToken.None,
        TaskCreationOptions.LongRunning, // guarantees separate thread
        TaskScheduler.Default)
    .Wait();

TaskCreationOptions.LongRunningパラメーターが重要だったのは、それがないと、呼び出しが同じスレッドでタスクを起動し続けるためです。次の擬似コードのようなものを使用して、C#5.0で機能するかどうかを確認できます。

await TaskEx.Run(async() => await Request.Content.ReadAsMultipartAsync(provider))
于 2013-03-06T22:14:17.960 に答える
10
于 2016-09-08T02:23:44.470 に答える
4

stackoverflow に関する別の回答targetFramework に関するブログ投稿の助けを借りて、4.5 に更新し、web.config で以下を追加/更新すると、この問題が修正されることがわかりました。

<system.web>
    <compilation debug="true" targetFramework="4.5"/>
</system.web>
<appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
于 2015-02-16T12:05:58.603 に答える