开发者社区> 问答> 正文

.NET上传文件有线程限制??

用.NET SDK上传文件时,使用多线程上传,每个BackgroundWorker调用PutObject上传一个文件。运行后各个BackgroundWorker都处于运行状态,但是每次只能同时上传2个文件,当某个文件上传完成后,后续的上传任务才开始,并始终保持同时2个在上传。。
使用分块上传时也是如此,每个分块使用一个BackgroundWorker进行UploadPart上传,情况还是只能同时上传2个分块,某分块上传完成后才可以有一个递补上来。。
请问有没有人遇到这种情况

展开
收起
seal031 2014-07-18 11:29:36 5393 0
2 条回答
写回答
取消 提交回答
  • LT是个伪程序员
    有问有答是美德!
    2014-07-24 09:46:57
    赞同 展开评论 打赏
  • ReNET上传文件有线程限制??
    发下主要代码,请大家帮忙看下原因,谢谢。。。
                    ObjectMetadata metadata = new ObjectMetadata();
                    metadata.ContentType = "application/file";
                    ClientConfiguration config = new ClientConfiguration();
                    config.ConnectionTimeout = -1; 
                    OssClient ossClient = new OssClient(new Uri("http://oss.aliyuncs.com"), AccessID, AccessKey, config);

                    //单文件上传
                    //fs = File.Open(FileToUpload, FileMode.Open);
                    //PutObjectResult Result = ossClient.PutObject(Bucket, Key, fs, metadata);

                    InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(Bucket, Key);
                    InitiateMultipartUploadResult initResult = ossClient.InitiateMultipartUpload(initRequest);

                    // 设置每块大小
                    int partSize = 1024 * 1024 * 3;

                    FileInfo partFile = new FileInfo(FileToUpload);
                    FileSize = partFile.Length;

                    // 计算分块数目
                    int partCount = (int)(partFile.Length / partSize);
                    if (partFile.Length % partSize != 0)
                    {
                        partCount++;
                    }

                    for (int i = 0; i < partCount; i++)
                    {
                        // 获取文件流
                        FileStream fis = new FileStream(partFile.FullName, FileMode.Open,FileAccess.Read);
                        
                        // 跳到每个分块的开头
                        long skipBytes = partSize * i;
                        fis.Position = skipBytes;

                        // 计算每个分块的大小
                        long size = partSize < partFile.Length - skipBytes ?
                                partSize : partFile.Length - skipBytes;

                        // 创建UploadPartRequest,上传分块
                        UploadPartRequest uploadPartRequest = new UploadPartRequest(Bucket, Key, initResult.UploadId);
                        uploadPartRequest.InputStream = fis;
                        uploadPartRequest.PartSize = size;
                        uploadPartRequest.PartNumber = (i + 1);

                        BackgroundWorker bw = new BackgroundWorker();
                        bw.WorkerReportsProgress = true;
                        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
                        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
                        bw.RunWorkerAsync(new object[] { ossClient, uploadPartRequest, partCount, fis, i + 1 });
                        Thread.Sleep(500);

            //线程工作
            void bw_DoWork(object sender, DoWorkEventArgs e)
            {
                object[] args = e.Argument as object[];
                OssClient ossClient = args[0] as OssClient;
                UploadPartRequest uploadPartRequest = args[1] as UploadPartRequest;
                int partCount = int.Parse(args[2].ToString());
                FileStream fis = args[3] as FileStream;
                int partNumber = int.Parse(args[4].ToString());

                long startPosition = fis.Position;
                //实例化watcher对象,用于监视进度、速度、剩余时间,并加入列表
                UploadWatcher watcher = new UploadWatcher() { partNumber = partNumber, startPosition = startPosition, uploadPosition=startPosition, fis = fis };
                itemList.Add(watcher);

                UploadPartResult uploadPartResult = ossClient.UploadPart(uploadPartRequest);  
                partETags.Add(uploadPartResult.PartETag);
                threadDoneCount += 1;
                e.Result = new object[] { ossClient, uploadPartRequest.UploadId, partCount };
                UploadSize += ((long)uploadPartRequest.PartSize);
            }


            //线程完成
            void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                object[] args = e.Result as object[];
                OssClient ossClient = args[0] as OssClient;
                string UploadId = args[1] as string;
                int partCount = int.Parse(args[2].ToString());
                //当最后一个线程执行完毕时,进行分块文件的合并
                if (threadDoneCount == partCount)
                {
                    CompleteMultipartUploadRequest completeReq = new CompleteMultipartUploadRequest(Bucket, Key, UploadId);
                    //对分块上传的返回信息按PartNumber排序,因为合并时要求必须是升序
                    var query = from q in partETags
                                orderby q.PartNumber ascending
                                select q;
                    List<PartETag> sortedPartETags = query.ToList<PartETag>();
                    foreach (PartETag partETag in sortedPartETags)
                    {
                        completeReq.PartETags.Add(partETag);
                    }
                    CompleteMultipartUploadResult completeResult = ossClient.CompleteMultipartUpload(completeReq);
                    UploadFilish = true;
                    UploadOK = true;
                    State = UploadState.done;
                }
            }

    -------------------------

    ReNET上传文件有线程限制??
    呃,解决了。SDK没有问题,是忘记设置.net的HttpRequest并发限制了,xp、win7默认限制都是2个。。。
    2014-07-18 14:36:40
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
多IO线程优化版 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载