调用一个委托却执行了两次

Imcx 2017-02-15 10:57:04


private HttpListener httpListener = new HttpListener();

public void Start(AsyncCallback callback)
{
httpListener.Start();
httpListener.BeginGetContext(endGetContext, callback);
}

private void endGetContext(IAsyncResult ar)
{
var callback = ar.AsyncState as AsyncCallback;

/*
* 下面创建了一个IAsyncResult
* 主要是为了把HttpListenerContext传递出去
*/
callback(ACTransfer.Create(new HttpContext(httpListener.EndGetContext(ar))));
if (httpListener != null)
{
httpListener.BeginGetContext(endGetContext, callback);//开始监听下一个
}
}

...全文
412 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
Imcx 2017-02-15
  • 打赏
  • 举报
回复
Imcx 2017-02-15
  • 打赏
  • 举报
回复
救命啦
Imcx 2017-02-15
  • 打赏
  • 举报
回复
还有,从本地访问服务器也试过,会执两次
Forty2 2017-02-15
  • 打赏
  • 举报
回复
引用 1 楼 Imcx_ 的回复:
... 2.用浏览器直接访问,每次返回的值都是2的倍数 3.去掉黄色部分代码加断点就只停止一次
浏览器可能要访问/favicon,用来浏览器栏显示网站的小图标。 建议你调试时检查context.Request.Url。
Imcx 2017-02-15
  • 打赏
  • 举报
回复
目前只发现如果加上了响应请求的代码就会执行两次 PS: 我还试过 1.在外面使用非匿名的方法 2.把响应请求的代码放到方法里 3.不使用using语法糖 这些都会跑两次
Imcx 2017-02-15
  • 打赏
  • 举报
回复

//从其他地方调用方法
.Start((ar) =>
{
    var context = ar.AsyncState as HttpContext;
    var request = context.Request;

    using (var writer = new System.IO.StreamWriter(context.Response.OutputStream))
    {
        writer.Write("return: " + i++);//这个i只是测试用的一个全局变量
    }
});

1.在这个匿名委托中加上断点,会停止两次 2.用浏览器直接访问,每次返回的值都是2的倍数 3.去掉黄色部分代码加断点就只停止一次
Imcx 2017-02-15
  • 打赏
  • 举报
回复
已经修改了,简单说明下,这里是自己写的一个HttpServer的类,用来接收一些简单的获取数据的请求,里面有一些相关业务的处理方法 通过实例化添加一个url到httpListener里去,外部通过

public void Start(Action<HttpListenerContext> callback)
{
    httpListener.Start();
    httpListener.BeginGetContext(endGetContext, callback);
}
开始接收并处理请求

HttpServer.Start((context) =>
{
    var request = context.Request;//用来访问请求
    //这里做些处理...
    using (var writer = new System.IO.StreamWriter(context.Response.OutputStream))
    {
        writer.Write("response");//响应消息
    }
});
我想请问的就是上面的代码会被执行两次是什么原因
Imcx 2017-02-15
  • 打赏
  • 举报
回复
引用 10 楼 sp1234_maJia 的回复:
如果你担心有没有先调用 EndGetContext语句(我并没有测试),你可以先调用它
private void endGetContext(IAsyncResult ar)
{
    var callback = ar.AsyncState as Action<HttpListenerContext>;
    var context = httpListener.EndGetContext(ar);
    httpListener.BeginGetContext(endGetContext, callback);//开始监听下一个
    callback(context);
}
但是,总之是先提高 I/O 效率,然后才 callback 业务处理。
非常感谢你的建议,我写过来的时候是把注释的代码删除了的,事实callback是写在最后面的 另外这个回调的参数是我自己封装的一个类,不过写在我先试试你说的这种
sp1234_maJia 2017-02-15
  • 打赏
  • 举报
回复
如果你担心有没有先调用 EndGetContext语句(我并没有测试),你可以先调用它
private void endGetContext(IAsyncResult ar)
{
    var callback = ar.AsyncState as Action<HttpListenerContext>;
    var context = httpListener.EndGetContext(ar);
    httpListener.BeginGetContext(endGetContext, callback);//开始监听下一个
    callback(context);
}
但是,总之是先提高 I/O 效率,然后才 callback 业务处理。
  • 打赏
  • 举报
回复
所谓“调用代码”是这样写的
.Start((context) =>
{
    using (var writer = new System.IO.StreamWriter(context.Response.OutputStream))
    {
        writer.Write("return: " + i++);//这个i只是测试用的一个全局变量
    }
});
直接使用 HttpListenerContext 来输出。注意不是 HttpContext,而是 HttpListenerContext。
  • 打赏
  • 举报
回复
callback 应该在“开始监听下一个”之后,应该及时先去监听下一个,而不是先回调然后才监听下一个。
  • 打赏
  • 举报
回复
看不懂你创建一个 HttpContext 对象是啥的呢?
private HttpListener httpListener = new HttpListener();

public void Start(Action<HttpListenerContext> callback)
{
    httpListener.Start();
    httpListener.BeginGetContext(endGetContext, callback);
}

private void endGetContext(IAsyncResult ar)
{
    var callback = ar.AsyncState as Action<HttpListenerContext>;
    httpListener.BeginGetContext(endGetContext, callback);//开始监听下一个
    callback(httpListener.EndGetContext(ar));
}
就这么几句代码,让你写的“稀碎”。

111,097

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧