我的API控制器一次只处理一个请求,由具有多个线程的控制台应用程序测试。每当请求到来时,当进程正在进行解析时,Web应用程序就会一直处于中断状态,直到进程完成。每个请求大约需要2.5秒才能完成。
这是我的控制器方法:
[HttpPost]
public async Task<IActionResult> Post()
{
return await Task.Run(async () =>
{
IActionResult result;
var rom = new ResultObjectModel();
try {
using (var reader = new StreamReader(Request.Body, Encoding.UTF8)) {
var serializer = new XmlSerializer(typeof(XmlDocument));
var obj = (XmlDocument) serializer.Deserialize(reader);
rom = await _service.ParseXML(obj);
}
} catch (Exception) {
// ignored
}
var file = await System.IO.File.ReadAllBytesAsync(rom.FileLocation);
if (!string.IsNullOrEmpty(rom.FileLocation)) {
switch (rom.ExportType) {
case "docx":
result = File(file, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "file.docx");
break;
case "docm":
result = File(file, "application/vnd.ms-word.document.macroEnabled.12", "file.docm");
break;
case "pdf":
result = File(file, "application/pdf", "file.pdf");
break;
default:
throw new ArgumentOutOfRangeException();
}
}
else
{
result = BadRequest();
}
return result;
});
}
ResultObjectModel
类只是一个简单的类,用于保存文件在文件系统中的位置以及文件的类型。
public class ResultObjectModel
{
public string FileLocation { get; set; }
public string ExportType { get; set; }
}
这是我的Program
课程及其BuildWebHost
方法。
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseLibuv(opt => opt.ThreadCount = 4)
.Build();
}
我会在请求正文中使用XML文件向API发送POST
请求。我解析该文件,在本地硬盘驱动器上创建包含某些特定数据的文档,然后使用byte[]
将该文档作为File.ReadAllBytesAsync()
返回。
编辑:
以下是发送请求的控制台应用,请注意我已隐藏了一些敏感信息,并将其替换为API_URL等字符串:
internal class Program {
private const string Uri = "API_URL";
private static readonly string FilesFolder =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TEST_FOLDER");
private static readonly string Body = File.ReadAllText("XML_FILE");
private static void DoStuff(int threadId, byte[] data) {
for (var a = 0; a < 50; a++) {
Console.WriteLine("Thread " + threadId + " , Request " + a + ".");
var request = (HttpWebRequest) WebRequest.Create(Uri);
request.ContentType = "application/xml";
request.Accept = "application/pdf";
request.Method = "POST";
var stream = request.GetRequestStream();
stream.Write(data, 0, data.Length);
stream.Close();
using (var response = request.GetResponse()) {
var ms = new MemoryStream();
response.GetResponseStream()?.CopyTo(ms);
File.WriteAllBytes(FilesFolder + "PDF_" + new Random().NextDouble() + ".pdf", ms.ToArray());
}
}
}
private static void Main() {
var data = Encoding.ASCII.GetBytes(Body);
var t1 = new Thread(() => { DoStuff(1, data); });
var t2 = new Thread(() => { DoStuff(2, data); });
var t3 = new Thread(() => { DoStuff(3, data); });
var t4 = new Thread(() => { DoStuff(4, data); });
t1.Start();
t2.Start();
t3.Start();
t4.Start();
}
}
它向api发送请求,收到byte[]
文件,然后将其保存为pdf。注意我也使用了Task.Run(()=> {});
,但结果是SAME。这是我第二次尝试使它发挥作用。