等待客户.GetStringAsync异常退出

本文关键字:退出 异常 GetStringAsync 客户 等待 | 更新日期: 2023-09-27 17:59:26

我关注这篇关于如何在ASP.NET Web API 2中使用批处理支持的博客文章。服务器代码似乎可以工作,并在端口12345上侦听。

当我运行客户端代码时,它到达以下行:

dynamic listOfCustomers = JToken.Parse(await client.GetStringAsync("http://localhost:12345/api/WebCustomers"));

并且在没有任何异常被抛出的情况下退出。以下是调试输出:

'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_32'mscorlib'v4.0_4.0.0.0__b77a5c561934e089'mscorlib.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'assembly'GAC_MSIL'Microsoft.VisualStudio.HostingProcess.Utilities'12.0.0.0__b03f5f7f11d50a3a'Microsoft.VisualStudio.HostingProcess.Utilities.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'System.Windows.Forms'v4.0_4.0.0.0__b77a5c561934e089'System.Windows.Forms.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'System.Drawing'v4.0_4.0.0.0__b03f5f7f11d50a3a'System.Drawing.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'System'v4.0_4.0.0.0__b77a5c561934e089'System.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'assembly'GAC_MSIL'Microsoft.VisualStudio.HostingProcess.Utilities.Sync'12.0.0.0__b03f5f7f11d50a3a'Microsoft.VisualStudio.HostingProcess.Utilities.Sync.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'assembly'GAC_MSIL'Microsoft.VisualStudio.Debugger.Runtime'12.0.0.0__b03f5f7f11d50a3a'Microsoft.VisualStudio.Debugger.Runtime.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'c:'users'documents'visual studio 2013'Projects'client_batch'client_batch'bin'Debug'client_batch.vshost.exe'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'System.Core'v4.0_4.0.0.0__b77a5c561934e089'System.Core.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'System.Xml.Linq'v4.0_4.0.0.0__b77a5c561934e089'System.Xml.Linq.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'System.Data.DataSetExtensions'v4.0_4.0.0.0__b77a5c561934e089'System.Data.DataSetExtensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'Microsoft.CSharp'v4.0_4.0.0.0__b03f5f7f11d50a3a'Microsoft.CSharp.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_32'System.Data'v4.0_4.0.0.0__b77a5c561934e089'System.Data.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'System.Xml'v4.0_4.0.0.0__b77a5c561934e089'System.Xml.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'System.Net.Http'v4.0_4.0.0.0__b03f5f7f11d50a3a'System.Net.Http.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
The thread 0x1b80 has exited with code 259 (0x103).
The thread 0x1fec has exited with code 259 (0x103).
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'c:'users'mryan.asavie'documents'visual studio 2013'Projects'client_batch'client_batch'bin'Debug'client_batch.exe'. Symbols loaded.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'c:'users'mryan.asavie'documents'visual studio 2013'Projects'client_batch'client_batch'bin'Debug'Newtonsoft.Json.dll'. Cannot find or open the PDB file.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'c:'users'mryan.asavie'documents'visual studio 2013'Projects'client_batch'client_batch'bin'Debug'System.Net.Http.Formatting.dll'. Cannot find or open the PDB file.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'c:'users'mryan.asavie'documents'visual studio 2013'Projects'client_batch'client_batch'bin'Debug'Ploeh.AutoFixture.dll'. Cannot find or open the PDB file.
'client_batch.vshost.exe' (CLR v4.0.30319: client_batch.vshost.exe): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'System.Configuration'v4.0_4.0.0.0__b03f5f7f11d50a3a'System.Configuration.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
The thread 0x1920 has exited with code 259 (0x103).
The thread 0x14ac has exited with code 259 (0x103).
The program '[7268] client_batch.vshost.exe' has exited with code 0 (0x0).

这是服务器的代码:

namespace MyWebApp
{
    class Program {
        static void Main(string[] args)
        {
            string serviceUrl = "http://localhost:12345";
            using (WebApp.Start(serviceUrl, Configuration))
            {
                Console.WriteLine("Service listening at {0}", serviceUrl);
                Console.WriteLine("Press any key to stop the service and exit the application");
                Console.ReadKey();
            }
        }
        private static void Configuration(IAppBuilder builder)
        {
            HttpConfiguration configuration = new HttpConfiguration();
            HttpServer server = new HttpServer(configuration);
            configuration.Routes.MapHttpRoute(
                name: "api",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional });
            builder.UseWebApi(server);
        }
        public class Customer
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
        public class WebCustomersController : ApiController
        {
            CustomersContext context = new CustomersContext();
            [Queryable(PageSize = 10, MaxExpansionDepth = 2)]
            public IHttpActionResult Get()
            {
                return Ok(context.Customers);
            }
            public async Task<IHttpActionResult> Post([FromBody] Customer entity)
            {
                if (entity == null)
                {
                    return BadRequest(ModelState);
                }
                context.Customers.Add(entity);
                await context.SaveChangesAsync();
                return CreatedAtRoute("api", new { controller = "ApiCustomers" }, entity);
            }
            public async Task<IHttpActionResult> Put(int id, [FromBody] Customer entity)
            {
                if (entity == null)
                {
                    return BadRequest(ModelState);
                }
                else if (id != entity.Id)
                {
                    return BadRequest("The key from the url must match the key of the entity in the body");
                }
                var originalCustomer = await context.Customers.FindAsync(id);
                if (originalCustomer == null)
                {
                    return NotFound();
                }
                else
                {
                    context.Entry(originalCustomer).CurrentValues.SetValues(entity);
                    await context.SaveChangesAsync();
                }
                return Content(HttpStatusCode.OK, entity);
            }
            public async Task<IHttpActionResult> Delete(int id)
            {
                Customer entity = await context.Customers.FindAsync(id);
                if (entity == null)
                {
                    return NotFound();
                }
                else
                {
                    context.Customers.Remove(entity);
                    await context.SaveChangesAsync();
                    return StatusCode(HttpStatusCode.NoContent);
                }
            }
        }
        public class CustomersContext : DbContext
        {
            static CustomersContext()
            {
                Database.SetInitializer<CustomersContext>(new CustomersContextInitializer());
            }
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
            }
            private class CustomersContextInitializer : DropCreateDatabaseAlways<CustomersContext>
            {
                protected override void Seed(CustomersContext context)
                {
                    Fixture fixture = new Fixture();
                    IEnumerable<Customer> customers = fixture.CreateMany<Customer>(20).ToList();
                    context.Customers.AddRange(customers);
                }
            }
            public DbSet<Customer> Customers { get; set; }
        }
    }
}

这是给客户的:

namespace client_batch
{
    class Program
    {
        static void Main(string[] args)
        {
            start();
        }
        private async static void start()
        {
            Fixture fixture = new Fixture();
            HttpClient client = new HttpClient();
            dynamic listOfCustomers = JToken.Parse(await client.GetStringAsync("http://localhost:12345/api/WebCustomers"));
            dynamic firstCustomer = listOfCustomers[0];
            firstCustomer.Name = "Peter";
            dynamic secondCustomer = listOfCustomers[1];
            JsonMediaTypeFormatter formatter = new JsonMediaTypeFormatter();
            //Create a request to query for customers
            HttpRequestMessage queryCustomers = new HttpRequestMessage(HttpMethod.Get, "http://localhost:12345/api/WebCustomers");
            //Create a message to add a customer
            HttpRequestMessage addCustomer = new HttpRequestMessage(HttpMethod.Post, "http://localhost:12345/api/WebCustomers");
            addCustomer.Content = new ObjectContent<Customer>(fixture.Create<Customer>(), formatter);
            //Create a message to update a customer
            HttpRequestMessage updateCustomer = new HttpRequestMessage(HttpMethod.Put, string.Format("http://localhost:12345/api/WebCustomers/{0}", firstCustomer.Id));
            updateCustomer.Content = new ObjectContent<dynamic>(firstCustomer, formatter);
            //Create a message to remove a customer.
            HttpRequestMessage removeCustomer = new HttpRequestMessage(HttpMethod.Delete, string.Format("http://localhost:12345/api/WebCustomers/{0}", secondCustomer.Id));
            //Create the different parts of the multipart content
            HttpMessageContent queryContent = new HttpMessageContent(queryCustomers);
            HttpMessageContent addCustomerContent = new HttpMessageContent(addCustomer);
            HttpMessageContent updateCustomerContent = new HttpMessageContent(updateCustomer);
            HttpMessageContent removeCustomerContent = new HttpMessageContent(removeCustomer);
            //Create the multipart/mixed message content
            MultipartContent content = new MultipartContent("mixed", "batch_" + Guid.NewGuid().ToString());
            content.Add(queryContent);
            content.Add(addCustomerContent);
            content.Add(updateCustomerContent);
            content.Add(removeCustomerContent);
            //Create the request to the batch service
            HttpRequestMessage batchRequest = new HttpRequestMessage(HttpMethod.Post, "http://localhost:12345/api/batch");
            //Associate the content with the message
            batchRequest.Content = content;
        }
        public class Customer
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
    }
}

我是c#的新手,所以任何建议都将不胜感激!

等待客户.GetStringAsync异常退出

当你在异步方法的代码中使用await关键字时,你真正告诉程序的是"听着,你继续做工作,完成后给我回电话(当然,这并没有那么简单,编译器为我们做了很多开销,我们看不到,你可以在这里阅读)"。

所以在你的代码中实际发生的是

dynamic listOfCustomers = JToken.Parse(await client.GetStringAsync("http://localhost:12345/api/WebCustomers"));

将控制权返回给调用者,在本例中,调用者是一个名为start()的方法,由于它是Main方法,因此无法等待。start得到了控制权,没有等待,所以下一行代码继续执行,这导致程序结束。

你需要做的是在开始时等待(),这样当控制权被收回时它就不会结束:

class Program
{
  static void Main(string[] args)
  {
    start().Wait();
  }
  private async static void start()
  {
    Fixture fixture = new Fixture();
    HttpClient client = new HttpClient();
    dynamic listOfCustomers = JToken.Parse(await client.GetStringAsync("http://localhost:12345/api/WebCustomers").ConfigureAwait(false));
     // Rest Of Code..
  }