我写了一个简单的测试WEB API,将docx文件转换为pdf(使用第三方库)。代码如下:
[Route("PDFConvert/Convert")]
[HttpPost]
public IHttpActionResult ConvertFile(string name)
{
var content = Request.Content.ReadAsStreamAsync().Result;
try
{
if (content != null)
{
using (MemoryStream ms = new MemoryStream())
{
content.CopyTo(ms);
Converter.Convert(ms.ToArray(), @".docx", @"c:\pdftest\" + name + @".pdf");
}
}
else
{
return Content(HttpStatusCode.InternalServerError, "No source file supplied.");
}
}
catch (Exception ex)
{
return InternalServerError(new Exception(ex.Message));
}
return Ok("File " + name + ".docx has been converted.");
}
此代码适用于单个呼叫。
然后我在控制台程序中编写了一些测试代码,以模拟有很多请求命中api,代码如下:
for (int i = 1; i < 101; i++)
{
var filestream = File.OpenRead(@"c:\pdftest\" + i.ToString() + @".docx");
test(filestream, i.ToString());
}
static void test(FileStream fs, string id)
{
var content = new StreamContent(fs);
var client = new HttpClient();
//post to web api
var response = client.PostAsync("http://localhost/WebAPI.PDFConvertion/PDFConvert/Convert?name=" + id, content);
Console.WriteLine("File Name: " + id + ".pdf");
client.Dispose();
}
此WEB API在IIS 7.5中托管,具有所有默认设置。
现在出现了问题:转换一些文件后(所有原始docx文件都是相同的,只是不同的文件名),整个过程就会停止。
在我的测试中,如果原始文件大小很大(> 1M),它在转换37个文件后总是停止,如果原始文件大小很小(如20KB),它总是在69之后停止。
如果我不使用API并将转换代码移动到控制台进行测试,那么所有好的,所有100个文件都会逐个转换。
在真实场景中,需要转换数千个docx文件,我们计划每个文件向API发出请求,这意味着在短时间内会有数千个请求。
那么,你们能解释一下如何解决这个问题吗?我是否需要修改IIS的某些设置?
如果您有任何疑问,请与我们联系。感谢。
答案 0 :(得分:0)
其实自己找到了解决方案。所有关于HttpClient的默认超时值为100秒。
因此,当有很多并发请求命中API时,其中一些会立即执行,其中一些必须等待免费资源。如果这些请求等待的时间太长,比httpclient超时时间长,则会发生错误。
因此,将超时值增加到所需的值,现在一切都很完美。
示例:
var client = new HttpClient();
client.Timeout = TimeSpan.FromMinutes(5);