代码之家  ›  专栏  ›  技术社区  ›  Andrey Bushman

为什么应用程序会毫无例外地愚蠢地死去?

  •  1
  • Andrey Bushman  · 技术社区  · 8 年前

    。净核心2

    当客户端试图发送 get 请求服务器。如果我使用 Postman 然后它工作得很好,但我需要通过C#来完成。这是我的一段代码,用于从服务器获取文件:

    var client = new HttpClient();
    client.Timeout = TimeSpan.FromMinutes(timeSpanFromMinutes);
    
    try
    {
        // At this code row the application shutdown without any exception. 
        // Even doesn't work the 'catch' block of try\catch...
        HttpResponseMessage response = await client.GetAsync(url + "/Home/Download/" + args[1], 
            HttpCompletionOption.ResponseContentRead);
        // I will not be here    
        Console.WriteLine("Response status code: {0}", response.StatusCode);
        if (response.StatusCode == HttpStatusCode.OK)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                await response.Content.CopyToAsync(ms);
                Console.WriteLine("Data successfully recieved from server. Data length: {0}",
                    ms.Length);
    
                string resultFileName = Path.Combine(resultFolder, new Guid().ToString()
                                                         + resultFileExtension);
                using (FileStream fs = new FileStream(resultFileName, FileMode.Create))
                {
                    fs.Read(ms.GetBuffer(), 0, (int) ms.Length);
                }
    
                Console.WriteLine("The result was saved in the '{0}' file.", resultFileName);
            }
        }
    }
    catch (Exception ex)
    {   // I will not be here
        Console.WriteLine("Exception: {0}", ex.Message);
    }
    

    服务器已启动并可访问。所有变量都已初始化并包含有效值。这个 post 请求工作正常。我有个问题 收到 要求我对问题代码行进行了注释。

    这种行为的原因是什么?

    UPD公司

    这是我客户端的完整代码(问题是“get”命令):

    using System;
    using System.IO;
    using System.Net;
    using System.Net.Http;
    using System.Reflection;
    using System.Threading.Tasks;
    using System.Xml.Linq;
    
    namespace Client
    {
        class Program
        {
            static void Main(string[] args)
            {
               var task = Task.Run(()=>{
                    Work(args);
               });
               task.Wait();
            }
    
            static async Task Work(string[] args)
            {
                if (args.Length != 2)
                {
                    Console.WriteLine("Application invalid parameters.");
                    WriteHelp();
                    return;
                }
    
                string xmlFileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
                    "Client.settings.xml");
    
                XElement xml = XElement.Load(xmlFileName);
    
                string url = xml.Element("url").Value?.Trim()?.TrimEnd('/');
                string resultFolder = Environment.ExpandEnvironmentVariables(xml.Element("resultsFolder").Value);
    
                if (!Directory.Exists(resultFolder))
                {
                    Directory.CreateDirectory(resultFolder);
                }
    
                string resultFileExtension = Environment.ExpandEnvironmentVariables(xml.Element("resultFileExtension").Value);
                int timeSpanFromMinutes = Int32.Parse(xml.Element("TimeSpanFromMinutes").Value);
    
                switch (args[0])
                {
                    // Send data to server
                    case "post":
                    {
                        string fileName = Environment.ExpandEnvironmentVariables(args[1]);
    
                        if (!File.Exists(fileName))
                        {
                            Console.WriteLine("File '{0}' not found.", fileName);
                            return;
                        }
                        else
                        {
                            var client = new HttpClient();
                            client.Timeout = TimeSpan.FromMinutes(timeSpanFromMinutes);
    
                            try
                            {
                                using (FileStream fs = new FileStream(fileName, FileMode.Open))
                                {
                                    HttpResponseMessage response = await client.PostAsync(url + "/Home/Upload", 
                                        new StreamContent(fs));
    
                                    Console.WriteLine("Response status code: {0}", response.StatusCode);
                                    if (response.StatusCode == HttpStatusCode.OK)
                                    {
                                        // The task ID. It is to be used for get the data handling result from server later.
                                        string id = await response.Content.ReadAsStringAsync();
                                        Console.WriteLine("Task ID: {0}", id);
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("Exception: {0}", ex.Message);
                            }
                        }
    
                        break;
                    }
                    // get the result of data handling from server
                    case "get":
                    {
                        Guid guid = Guid.Empty;
    
                        if (!Guid.TryParse(args[1], out guid))
                        {
                            Console.WriteLine("Invalid identifier (GUID): '{0}'", args[1]);
                            return;
                        }
    
                        var client = new HttpClient();
                        client.Timeout = TimeSpan.FromMinutes(timeSpanFromMinutes);
    
                            try
                            {
                                // TODO: the problem is here
                                var response = await client.GetAsync(url + "/Home/Download/" + args[1], 
                                    HttpCompletionOption.ResponseContentRead);
    
                                Console.WriteLine("Response status code: {0}", response.StatusCode);
                                if (response.StatusCode == HttpStatusCode.OK)
                                {
                                    using (MemoryStream ms = new MemoryStream())
                                    {
                                        await response.Content.CopyToAsync(ms);
                                        Console.WriteLine("Data successfully recieved from server. Data length: {0}",
                                            ms.Length);
    
                                        string resultFileName = Path.Combine(resultFolder, new Guid().ToString()
                                                                                 + resultFileExtension);
                                        using (FileStream fs = new FileStream(resultFileName, FileMode.Create))
                                        {
                                            fs.Read(ms.GetBuffer(), 0, (int) ms.Length);
                                        }
    
                                        Console.WriteLine("The result was saved in the '{0}' file.", resultFileName);
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("Exception: {0}", ex.Message);
                            }
    
                        break;
                    }
                    default:
                    {
                        Console.WriteLine("Unknown command: {0}", args[0]);
                        WriteHelp();
                        return;
                    }
                } 
            }
    
            private static void WriteHelp()
            {
                string text =
    @"
    Client.dll
    (c) Andrey Bushman, 2018
    
    This client allows to send data to server and get the results of their handling.
    
    The application using format:
    
        dotnet Client.dll <command> <parameter>
    
    ## COMMAND
    
        post - send file to server. The request contains status code and GUID for getting the data handling result later.
    
        get - get data handling result by GUID. If result doesn't exist still then recuest code is 'File not found'. 
    
    ## PARAMETER
    
        It is the file full name for the 'post' command or the GUID for the 'get' command.
    
    ## EXAMPLES
    
    Upload the file to server:
    
        dotnet Client.dll post /home/andrey/tmp/data.foo
    
    Download the data handling result from server by GUID:
    
        dotnet Client.dll get 3d600895-f11c-4fa0-865e-411d52daf469";
    
                Console.WriteLine(text);
            }
        }
    }
    

    完整代码源包括 here 在GitHub上。

    1 回复  |  直到 8 年前
        1
  •  3
  •   Henk Holterman    8 年前

    请注意编译器警告:

     var task = Task.Run(()=>{
         Work(args);
     });
     task.Wait();
    

    它应该告诉你 Work(args) 没有在这里等待。这意味着它抛出的任何例外都将不被注意到。

    由于我们使用的是控制台应用程序, Task.Run() 没有真正的目的。
    请使用以下选项:

    static void Main(string[] args)
    {
        try
        {
            var task = Work(args);
            task.Wait();
        }
        catch (Exception ex)
        {
           // log or put a breakpoint here        
        }
    }