首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows Phone 8 http post文件上载超时

Windows Phone 8 http post文件上载超时
EN

Stack Overflow用户
提问于 2014-05-07 02:31:46
回答 2查看 621关注 0票数 1

我正在开发一个Windows phone8应用程序,需要上传照片到亚马逊s3存储。但是,我发现这是不可能的,因为无论我使用什么超时设置,HttpClient都会在大约60秒后超时。

真的没有办法从Windows Phone上传大文件吗?

BackgroundTransferRequest是无用的,因为它不能通过文件上传发送必要的元数据。

我使用以下代码(超时):

代码语言:javascript
复制
using (var httpClient = new HttpClient())
{
    httpClient.Timeout = TimeSpan.FromMinutes(30);
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, m_uploadUrl);
    httpContent.Headers.Add("Keep-Alive", "true");
    request.Content = httpContent; // 3-5 Mb file 
    response = await httpClient.SendAsync(request);
    statusCode = response.StatusCode;
}

我也尝试了PostAsync(),但结果相同。大约60秒后,调用结束,状态码为400或404。这不是服务器超时。IPhone和安卓应用程序使用相同的服务。这没什么问题。

对于如何上传超过60秒才能发送的文件有什么建议吗?

EN

回答 2

Stack Overflow用户

发布于 2014-05-07 15:23:57

我也遇到过类似的事情。超时故障。检查是否可以使用另一个类来代替HttpClient。WebClient可能就是。

检查这是否对您有帮助:http://blog.anthonybaker.me/2013/06/how-to-upload-file-from-windows-phone.html

甚至还有这个:http://chriskoenig.net/2011/08/19/upload-files-from-windows-phone/

有了这些,我的事情就好办了。

票数 0
EN

Stack Overflow用户

发布于 2014-05-19 01:34:51

我现在已经用了几天的时间来实现一个新的上传程序,并让所有的细节都工作起来。我将HttpWebRequest与异步方法结合使用,并将文件拆分成块。最后,我让它正常工作,它在没有超时的情况下上传。下面是完整的代码:

代码语言:javascript
复制
using System;
using Models;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Services
{
    public class UploadData
    {
        public Stream PostStream { get; set; }
        public Stream FileStream { get; set; }
        public byte[] HeaderBytes {get; set;}
        public byte[] FooterBytes  {get; set;}
        public byte[] Buffer { get; set; }
        public Photo Upload { get; set; }
        public int BytesWritten { get; set; }
    }

    public class UploadEventArgs : EventArgs
    {
        public Photo Upload { get; set; }
        public int Progress { get; set; }
    }

    public class UploadService
    {
        public delegate void CompletedEventHandler(object sender, UploadEventArgs e);
        public event CompletedEventHandler UploadCompleted;
        public delegate void ProgressEventHandler(object sender, UploadEventArgs e);
        public event ProgressEventHandler ProgressChanged;

        private static string contentType = "multipart/form-data; boundary={0}";
        private static string headerString = "Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\r\nContent-Type: Content-Type: application/octet-stream\r\n\r\n";
        private HttpWebRequest m_request;
        private static string boundarystr;

        private UploadData m_uploadData;
        private bool m_isStopped;

        public async Task StartUpload(Photo upload, Uri uri, Dictionary<string, string> parameters)
        {
            try
            {
                m_isStopped = false;
                var fileStream = (await upload.File.OpenReadAsync()).AsStreamForRead();

                var uploadData = new UploadData();

                boundarystr = "---------------------------" + DateTime.Now.Ticks.ToString("x");
                string para = GetParamsString(parameters);
                string headAndParams = para + String.Format(headerString, HttpUtility.UrlEncode(upload.File.Name));

                var headerBytes = System.Text.Encoding.UTF8.GetBytes(headAndParams);
                var footerBytes = Encoding.UTF8.GetBytes("\r\n--" + boundarystr + "--\r\n");

                uploadData.Upload = upload;
                uploadData.FileStream = fileStream;
                uploadData.FooterBytes = footerBytes;
                uploadData.HeaderBytes = headerBytes;
                uploadData.BytesWritten = 0;
                m_uploadData = uploadData;
                m_request = (HttpWebRequest)WebRequest.Create(uri);
                m_request.Method = "POST";
                m_request.AllowWriteStreamBuffering = false;
                m_request.ContentType = string.Format(contentType, boundarystr);
                m_request.ContentLength = fileStream.Length + headerBytes.Length + footerBytes.Length;
                var asyncResult = m_request.BeginGetRequestStream((ar) => { GetRequestStreamCallback(ar, uploadData); }, m_request);
            }
            catch (Exception ex)
            {
                m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
                m_uploadData.Upload.UploadInfo.Exception = new Exception("Start upload failed: " + ex.Message);
                var argsStopped = new UploadEventArgs();
                argsStopped.Upload = m_uploadData.Upload;
                m_uploadData.FileStream.Close();
                m_uploadData.PostStream.Close();
                OnUploadComplete(argsStopped);
            }
        }

        private void GetRequestStreamCallback(IAsyncResult asynchronousResult, UploadData uploadData)
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
                Stream postStream = request.EndGetRequestStream(asynchronousResult);

                postStream.Write(uploadData.HeaderBytes, 0, uploadData.HeaderBytes.Length);

                var args = new UploadEventArgs();
                args.Upload = uploadData.Upload;
                args.Progress = 1;
                OnProgressChanged(args);
                uploadData.PostStream = postStream;

                WriteNextChunck(uploadData);
            }
            catch (Exception ex)
            {
                m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
                m_uploadData.Upload.UploadInfo.Exception = new Exception("Header write failed: " + ex.Message);
                var argsStopped = new UploadEventArgs();
                argsStopped.Upload = m_uploadData.Upload;
                m_uploadData.FileStream.Close();
                m_uploadData.PostStream.Close();
                OnUploadComplete(argsStopped);
            }
        }

        private void WriteNextChunck(UploadData upload)
        {
            try
            {
                if ((upload.FileStream.Length - upload.BytesWritten) >= 16 * 1024)
                {
                    upload.Buffer = new byte[16 * 1024];
                }
                else
                {
                    // Last part
                    upload.Buffer = new byte[upload.FileStream.Length - upload.BytesWritten];
                }

                upload.FileStream.Read(upload.Buffer, 0, (int)upload.Buffer.Length);
                upload.PostStream.BeginWrite(upload.Buffer, 0, upload.Buffer.Length, BeginWriteCallback, upload);
            }
            catch (Exception ex)
            {
                m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
                m_uploadData.Upload.UploadInfo.Exception = new Exception("Buffer write failed: " + ex.Message);
                var argsStopped = new UploadEventArgs();
                argsStopped.Upload = m_uploadData.Upload;
                upload.FileStream.Close();
                upload.PostStream.Close();
                OnUploadComplete(argsStopped);
            }
        }

        private void BeginWriteCallback(IAsyncResult ar)
        {
            try
            {
                var upload = ar.AsyncState as UploadData;
                upload.PostStream.EndWrite(ar);
                upload.BytesWritten += upload.Buffer.Length;

                var args = new UploadEventArgs();
                args.Upload = upload.Upload;
                args.Progress = (int)(((decimal)upload.BytesWritten / (decimal)upload.FileStream.Length) * 100);
                OnProgressChanged(args);

                if (m_isStopped)
                {
                    upload.FileStream.Close();
                    upload.PostStream.Close();
                    m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
                    m_uploadData.Upload.UploadInfo.Exception = new Exception("Upload stopped");
                    var argsStopped = new UploadEventArgs();
                    argsStopped.Upload = m_uploadData.Upload;
                    OnUploadComplete(argsStopped);
                    return;
                }

                // write next chunck
                if (upload.BytesWritten < upload.FileStream.Length)
                {
                    WriteNextChunck(upload);
                }
                if (upload.BytesWritten >= upload.FileStream.Length)
                {
                    WriteFooter(upload);
                }
            }
            catch (Exception ex)
            {
                m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
                m_uploadData.Upload.UploadInfo.Exception = new Exception("Upload write failed: " + ex.Message);
                var argsStopped = new UploadEventArgs();
                argsStopped.Upload = m_uploadData.Upload;
                OnUploadComplete(argsStopped);
            }
        }

        private void WriteFooter(UploadData upload)
        {
            try
            {
                upload.PostStream.Write(upload.FooterBytes, 0, upload.FooterBytes.Length);
                upload.PostStream.Close();
                var asyncResult = m_request.BeginGetResponse(new AsyncCallback(GetResponseCallback), m_request);
            }
            catch (Exception ex)
            {
                m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
                m_uploadData.Upload.UploadInfo.Exception = new Exception("Footer write failed: " + ex.Message);
                var argsStopped = new UploadEventArgs();
                argsStopped.Upload = m_uploadData.Upload;
                OnUploadComplete(argsStopped);
            }
        }

        private void GetResponseCallback(IAsyncResult asynchronousResult)
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
                Stream streamResponse = response.GetResponseStream();
                StreamReader streamRead = new StreamReader(streamResponse);
                string responseString = streamRead.ReadToEnd();
                streamResponse.Close();
                streamRead.Close();
                response.Close();

                m_uploadData.FileStream.Close();
                m_uploadData.Upload.UploadInfo.StatusCode = response.StatusCode;

                if (response.StatusCode == HttpStatusCode.NoContent)
                {
                    m_uploadData.Upload.UploadInfo.Exception = null;
                }
                else
                {
                    m_uploadData.Upload.UploadInfo.Exception = new Exception(responseString);
                }
                var args = new UploadEventArgs();
                args.Upload = m_uploadData.Upload;
                args.Progress = 100;
                OnUploadComplete(args);
            }
            catch (Exception ex)
            {
                m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
                m_uploadData.Upload.UploadInfo.Exception = ex;
                var args = new UploadEventArgs();
                args.Upload = m_uploadData.Upload;
                OnUploadComplete(args);
            }
        }  

        private string GetParamsString(Dictionary<string, string> parameters)
        {
            bool needsCLRF = false;
            string result = "";
            foreach (var param in parameters)
            {
                // Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
                // Skip it on the first parameter, add it to subsequent parameters.
                if (needsCLRF)
                    result += "\r\n";

                needsCLRF = true;

                string prm = string.Format("--{0}\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Disposition: form-data; name={1}\r\n\r\n{2}",
                        boundarystr,
                        param.Key,
                        param.Value);
                result += prm;

            }

            // Add the end of the request.  Start with a newline
            string footer = "\r\n--" + boundarystr + "\r\n";
            result += footer;

            return result;
        }

        protected virtual void OnUploadComplete(UploadEventArgs e)
        {
            if (UploadCompleted != null)
                UploadCompleted(this, e);
        }

        protected virtual void OnProgressChanged(UploadEventArgs e)
        {
            if (ProgressChanged != null)
                ProgressChanged(this, e);
        }

        public void Stop()
        {
            m_isStopped = true;
        }

    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23502295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档