14

何らかの理由で、以前は機能していた以下のコードで例外が発生するようになりました。

public static async Task<string> HttpPut(string inUrl, string inFilePath)
    {
        using (var handler = new HttpClientHandler
        {
            AllowAutoRedirect = false
        })
        {
            using (var client = new HttpClient(handler))
            {
                //var content = new StreamContent(new FileStream(inFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true));
                using (var content = new StreamContent(new FileStream(inFilePath, FileMode.Open)))
                {
                    content.Headers.Remove("Content-Type");
                    content.Headers.Add("Content-Type", "application/octet-stream");

                    using (var req = new HttpRequestMessage(HttpMethod.Put, inUrl))
                    {
                        string authInfo = String.Format("{0}:{1}", Program.Config.MediaStorageList.Find(o => o.Name == "Viz Media Engine Test").UserName, Program.Config.MediaStorageList.Find(o => o.Name == "Viz Media Engine Test").Password);
                        authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
                        req.Headers.Add("Authorization", "Basic " + authInfo);
                        req.Headers.Remove("Expect");
                        req.Headers.Add("Expect", "");
                        //req.Headers.TransferEncodingChunked = true;

                        req.Content = content;

                        // Ignore Certificate validation failures (aka untrusted certificate + certificate chains)
                        ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);

                        using (HttpResponseMessage resp = await client.SendAsync(req))
                        {
                            //This part is specific to the setup on an Expo we're at...
                            if (resp.StatusCode == HttpStatusCode.Redirect || resp.StatusCode == HttpStatusCode.TemporaryRedirect)
                            {
                                string redirectUrl = resp.Headers.Location.ToString();

                                if (redirectUrl.Contains("vme-store"))
                                {
                                    redirectUrl = redirectUrl.Replace("vme-store", "10.230.0.11");
                                }
                                return await HttpPut(redirectUrl, inFilePath);
                            }

                            resp.EnsureSuccessStatusCode();

                            return await resp.Content.ReadAsStringAsync();
                        }
                    }
                }
            }
        }
    }

私が得ている例外は次のとおりです。

System.NotSupportedException was unhandled
HResult=-2146233067
Message=The stream does not support concurrent IO read or write operations.
Source=System
StackTrace:
     at System.Net.ConnectStream.InternalWrite(Boolean async, Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   at System.Net.ConnectStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   at System.Net.Http.StreamToStreamCopy.BufferReadCallback(IAsyncResult ar)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at VizWolfInnerServer.Tools.HttpConnector.<HttpPut>d__39.MoveNext() in c:\Users\christer\Documents\Visual Studio 2012\Projects\VizWolfNew\VizWolfInnerServer\Tools\HttpConnector.cs:line 202
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at VizWolfInnerServer.Tools.VizAPIConnector.<VmeUploadMedia>d__0.MoveNext() in c:\Users\christer\Documents\Visual Studio 2012\Projects\VizWolfNew\VizWolfInnerServer\Tools\VizAPIConnector.cs:line 187
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__1(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
InnerException: 

私はHttpClientの適切なドキュメントと例を見つけるのに非常に苦労しています.なぜこれが突然機能しないのかを理解するのに苦労しています.

もともとは独自のスレッドから呼び出され、次のようになります。

public static async void VmeUploadMedia(string inUploadLink, string inFilePath)
{
    string result = await HttpConnector.HttpPut(inUploadLink, inFilePath);
}

明らかな何かを見つけた人はいますか?

ありがとう

アップデート

元のコードに戻ることができるように、expo-guysにストレージ名をIPにマップしてもらうことが最善の解決策であることが判明しました。私が抱えていた問題は、AllowAutoRedirect = false と関係があります。実際にリダイレクトが行われていなくても、HttpResponseMessage resp = await client.SendAsync(req) で例外が発生しました。なぜそれが起こったのか、私はちょっと迷っていますが、このコードを使用すると、すべてが機能しています。

public static async Task<string> HttpPut(string inUrl, string inFilePath)
    {
        using (var client = new HttpClient())
        {
            using (var content = new StreamContent(File.OpenRead(inFilePath)))
            {
                content.Headers.Remove("Content-Type");
                content.Headers.Add("Content-Type", "application/octet-stream");

                using (var req = new HttpRequestMessage(HttpMethod.Put, inUrl))
                {
                    string authInfo = String.Format("{0}:{1}", Program.Config.MediaStorageList.Find(o => o.Name == "Viz Media Engine Test").UserName, Program.Config.MediaStorageList.Find(o => o.Name == "Viz Media Engine Test").Password);
                    authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
                    req.Headers.Add("Authorization", "Basic " + authInfo);
                    req.Headers.Remove("Expect");
                    req.Headers.Add("Expect", "");

                    req.Content = content;

                    // Ignore Certificate validation failures (aka untrusted certificate + certificate chains)
                    ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);

                    using (HttpResponseMessage resp = await client.SendAsync(req))
                    {
                        resp.EnsureSuccessStatusCode();

                        return await resp.Content.ReadAsStringAsync();
                    }
                }
            }
        }
    }

助けようとしてくれた人たちに感謝

4

3 に答える 3

1
using (HttpResponseMessage resp = await client.SendAsync(req))

この行は、その実行のための新しいコンテキストを作成するようです。したがって、新しいスレッド コンテキストが作成されます。FileStream のロックを共有するため、おそらくそれを行うことはできません。

于 2013-04-08T18:21:07.343 に答える
0

再度電話をかけているようですがHttpPut()、まだFileStream開いています。内部から再帰的に呼び出す前に、FileStream を破棄してみてくださいHttpPut()

//This part is specific to the setup on an Expo we're at...
                            if (resp.StatusCode == HttpStatusCode.Redirect || resp.StatusCode == HttpStatusCode.TemporaryRedirect)
                            {
                                string redirectUrl = resp.Headers.Location.ToString();

                                if (redirectUrl.Contains("vme-store"))
                                {

                                    redirectUrl = redirectUrl.Replace("vme-store", "10.230.0.11");
                                }
                                content.Dispose();
                                return await HttpPut(redirectUrl, inFilePath);
                        }

さらに、スタック トレースの詳細に進む前に、すべてのリソースが確実に解放されるように、http 応答などの他の IDisposable オブジェクトを破棄することをお勧めします。これは再帰の問題の 1 つであり、Usingステートメントを使用している間はそのスコープを離れないため、ステートメントは機能していません。

于 2013-04-08T18:20:41.260 に答える