【发布时间】:2018-11-29 12:48:38
【问题描述】:
我也有类似Here 的问题,但在我的客户端上使用了 WebClient 类以及来自this answere 的第二个代码示例。
那么我该怎么做才能只接到来自我的 WebClient 客户端的一个电话?
我的 httplistener 回调被调用了两次,第一个没问题,但第二个在 HttpListenerContext context = Listener.EndGetContext(ar); 处抛出此错误
System.Net.HttpListenerException: 'I/O 操作已因线程退出或应用程序请求而中止'
服务器代码:
private void DoWork(object arg)
{
Listener = new HttpListener();
Listener.Prefixes.Add("https://+:28210");
Listener.AuthenticationSchemes = AuthenticationSchemes.Basic;
Console.WriteLine("Listening...");
Listener.Start();
Listener.BeginGetContext(ListenerContext, null);
Console.ReadKey();
}
`
private static void ListenerContext(IAsyncResult ar)
{
Console.WriteLine("Get Data...");
HttpListenerContext context = Listener.EndGetContext(ar);
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
HttpListenerBasicIdentity identity = (HttpListenerBasicIdentity)context.User.Identity;
Listener.BeginGetContext(ListenerContext, null);
Console.WriteLine("Got Data!");
//Some more Code...
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseData);
response.ContentLength64 = buffer.Length;
System.IO.Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
}
客户代码:
using (WebClient client = new WebClient())
{
string serialisedData = JsonConvert.SerializeObject(Data);
client.Credentials = new NetworkCredential(config.UserData.Username, config.UserData.Password);
byte[] responsebyte = client.UploadData(config.ServerAddress, System.Text.Encoding.UTF8.GetBytes(serialisedData));
response = System.Text.Encoding.UTF8.GetString(responsebyte);
}
【问题讨论】:
-
没有得到答案的问题通常需要改进,而不是碰撞。 Thread 异常中止与“调用两次”无关,这意味着代码中存在线程问题。也许在应用程序终止时请求还没有完成?
EndGetContext和其余代码在哪里? -
BTW async/await 被引入以避免这些错误。而不是
BeginGetContext使用GetContextAsync,例如var context=await listener.GetContextAsync(); -
完整异常包含导致异常的调用堆栈和任何内部异常。您可以通过
Exception.ToString()轻松获取。调用堆栈将显示问题实际发生的位置以及导致问题的路径。将完整的异常与您的代码一起发布 -
第二次调用
ListenerContext时出现异常。如果我启动我的客户端,ListenerContext在没有问题的情况下运行,但奇怪的是它在第一个完成后第二次被调用。EndGetContext位于ListenerContext的第 2 行。代码的其余部分只是与数据一起发生的简单内容。我可以尝试使用GetContextAsync。 -
并且异常消息清楚地表明某事中止了操作。也许是原始的 HttpListener 被 GC 处理掉了——DoWork 每次都会启动一个新实例。或者应用程序在没有取消操作的情况下终止。这就是其余代码很重要的原因。
标签: c# .net webclient httplistener