下面这段C#代码中的线程池部分还是Java的写法,请大神门帮忙改成C#写法。
示例代码,最终代码啥的都很欢迎!
////// 用户初始化ak和sk,sdk自己生成token /// /// /// /// /// /// public virtual void execUpload(string bucketName, string fileKey, string randomFile, PutPolicy putPolicy, PutExtra putExtra, JSONObjectRet jsonObjectRet) { FileInfo randomFileInfo = null; ExecutorService pool = null; HttpClient mkfileHttpClient = null; int retry = 0; while (retry < 3) { string uploadBatch = "SDK-" + Guid.NewGuid();// UUID.randomUUID(); retry++; try { if (BaseBlockUtil.BLOCK_SIZE < 4 * BaseBlockUtil.MB || (BaseBlockUtil.BLOCK_SIZE % 4 * BaseBlockUtil.MB) != 0) { jsonObjectRet.onFailure(new Exception("块大小应该为4M的整数倍!")); return; } randomFileInfo = new FileInfo(randomFile); pool = Executors.newFixedThreadPool(BaseBlockUtil.THREAD_NUN); CompletionServicecompletionService = new ExecutorCompletionService (pool); if (putExtra.processes == null || putExtra.totalSize != randomFileInfo.Length) { initPutExtra(bucketName, fileKey, randomFile, putExtra, jsonObjectRet); } putExtra.totalSize = randomFileInfo.Length; putPolicy.deadline = Convert.ToString(DateUtil.ToJavaMilliseconds(DateUtil.nextNHours(1, DateTime.Now))); DateTime dealEndDate = DateUtil.nextNMinutes(5, DateTime.Now); string token = TokenUtil.getUploadToken(putPolicy); int runnerThread = 0; foreach (BlockObject blockObject in putExtra.processes) { runnerThread++; while (runnerThread > (BaseBlockUtil.THREAD_NUN + 1)) { completionService.take().get(); runnerThread--; } if (dealEndDate < DateTime.Now) { dealEndDate = DateUtil.nextNMinutes(5, DateTime.Now); putPolicy.deadline = Convert.ToString(DateUtil.ToJavaMilliseconds(DateUtil.nextNHours(1, DateTime.Now))); token = TokenUtil.getUploadToken(putPolicy); } //RandomAccessFile blockFile = new RandomAccessFile(randomFile, "r"); blockObject.setCommonParam(randomFile, bucketName, fileKey); HttpClient httpClient = new HttpClient(); BlockUpload task = new BlockUpload(blockObject, jsonObjectRet, putExtra, token, httpClient, uploadBatch); completionService.submit(task); } for (int i = 0; i < runnerThread; i++) { completionService.take().get(); } pool.shutdown(); putPolicy.deadline = Convert.ToString(DateUtil.ToJavaMilliseconds(DateUtil.nextNHours(1, DateTime.Now))); token = TokenUtil.getUploadToken(putPolicy); mkfileHttpClient = WebRequestMethods.Http.HttpClient; BaseBlockUtil util = new BaseBlockUtil(null, jsonObjectRet, putExtra, token, mkfileHttpClient); SliceUploadHttpResult result = util.mkfile(token, fileKey, putExtra, 0, uploadBatch); if (result.Status == 200) { string hash = WetagUtil.getEtagHash(randomFile); if (result.Hash.Equals(hash)) { jsonObjectRet.onSuccess(result.toJSON()); break; } else { Console.WriteLine(fileKey + " 文件hash与服务器不一致,文件重新上传"); putPolicy.overwrite = 1; putExtra.processes = null; } } else { if (result.Status == 412) { Console.WriteLine(fileKey + " 此文件块有缺失,文件重新上传"); putPolicy.overwrite = 1; putExtra.processes = null; } else { jsonObjectRet.onFailure(new HttpClientException(result.Status, result.Response)); break; } } } catch (Exception e) { jsonObjectRet.onFailure(e); } finally { if (pool != null) { pool.shutdownNow(); } if (mkfileHttpClient != null) { try { mkfileHttpClient.close(); } catch (IOException) { } } if (randomFileInfo != null) { try { int reTime = 0; while (!pool.Terminated && reTime < 50) { reTime++; Thread.Sleep(1000); } } catch (Exception) { Console.WriteLine("file close error"); } } } } }
C# 的 ThreadPool 使用起来比较简单,可以参考一下文档,主要是通过 QueueUserWorkItem(WaitCallback)
方法来启动一个任务(线程任务),其中 WaitCallback 是一个委托,可以使用 Lambda 表达式来写。
另外也可以用 System.Threading.Tasks.Task 来实现线程池的操作,相关的资料在网上很容易找到。
总的来说 .NET 的线程池不需要过多的去处理线程池本身的事情,只需要关注业务就好。关于线程池的大小,可以用 ThreadPool.SetMaxThreads
和 ThreadPool.SetMinThreads
来设置,但是一般不需要去处理。