动作一次只处理一个请求

时间:2018-05-07 12:41:24

标签: c# asp.net-core

我的API控制器一次只处理一个请求,由具有多个线程的控制台应用程序测试。每当请求到来时,当进程正在进行解析时,Web应用程序就会一直处于中断状态,直到进程完成。每个请求大约需要2.5秒才能完成。

enter image description here

这是我的控制器方法:

[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。这是我第二次尝试使它发挥作用。

0 个答案:

没有答案
相关问题