Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# HTTPListenerContext响应错误的客户端_C#_Multithreading_Http_F# - Fatal编程技术网

C# HTTPListenerContext响应错误的客户端

C# HTTPListenerContext响应错误的客户端,c#,multithreading,http,f#,C#,Multithreading,Http,F#,我遇到了一个非常奇怪的场景,我使用HTTP构建的服务器应用程序总是开始错误地响应客户端请求。服务器是一个简单的程序,位于数据库之上,允许通过从查询/请求层次结构发送序列化对象来查询该数据库 我使用F#编写的简单可重用HTTP服务器,使用邮箱处理器异步接收和服务请求: type public-HttpAgent(端口:int,处理程序:System.Action)= 让tokenSource=new CancellationTokenSource() let processorBody(邮箱:Ma

我遇到了一个非常奇怪的场景,我使用HTTP构建的服务器应用程序总是开始错误地响应客户端请求。服务器是一个简单的程序,位于数据库之上,允许通过从查询/请求层次结构发送序列化对象来查询该数据库

我使用F#编写的简单可重用HTTP服务器,使用邮箱处理器异步接收和服务请求:

type public-HttpAgent(端口:int,处理程序:System.Action)=
让tokenSource=new CancellationTokenSource()
let processorBody(邮箱:MailboxProcessor)=
异步的{
尽管如此
let!context=mailbox.Receive()
Async.Start(Async{handler.Invoke(context)})
}
让代理=新的MailboxProcessor(processorBody,tokenSource.Token)
member public x.Start()=//启动在指定端口上侦听的服务器
agent.Start()
让服务器=异步{
使用侦听器=新的HttpListener()
Add(String.Format(“http://*:{0}/”,端口))
listener.Start()
尽管如此
let!context=listener.AsyncGetContext()
agent.Post(上下文)
}
do Async.Start(服务器,cancellationToken=tokenSource.Token)
成员public x.Stop()=//停止代理服务器
tokenSource.Cancel()
正如您所看到的,为了运行服务器,您只需为邮箱异步接收的每个请求上下文提供一个要调用的操作

位于数据库顶部的实际服务器如下所示:

Func<QueryRequest, QueryResponse> tryQueryLookup = (request) => {
    if (request is RequestTypeA) {
        // attempt to retrieve from database
    } else if (request is RequestTypeB) {
        // attempt to retreive from database
    }

    // ... etc

    if (querySuccessful) {
        return new QueryResponse(databaseResults);
    } else {
        return new QueryResponse("Error");
    }
}

Action<HttpListenerContext> requestParser = (context) => {
    Action<QueryResponse> writeResponse = (response) => {
        try {
            using (StreamWriter streamWriter = new StreamWriter(context.Response.OutputStream)) {
                streamWriter.Write(response.ToXml());
            }
        } catch (Exception ex) {
            // write error message to event log
        }   
    };

    try {
        QueryRequest request = null;
        string requestBytes = new StreamReader(context.Request.InputStream).ReadToEnd();
        request = requestBytes.FromXml<QueryRequest>();
        writeResponse(tryQueryLookup(request));
    } catch (Exception ex) {
        writeResponse(new QueryResponse("Error"));
    }
};

m_HttpAgent = new HttpAgent(port, requestParser);
m_HttpAgent.Start()
Func-tryQueryLookup=(请求)=>{
如果(请求为RequestTypeA){
//尝试从数据库中检索
}else if(请求为RequestTypeB){
//尝试从数据库检索
}
//…等等
如果(查询成功){
返回新的QueryResponse(数据库结果);
}否则{
返回新的QueryResponse(“错误”);
}
}
Action requestParser=(上下文)=>{
操作writeResponse=(响应)=>{
试一试{
使用(StreamWriter StreamWriter=newstreamwriter(context.Response.OutputStream)){
streamWriter.Write(response.ToXml());
}
}捕获(例外情况除外){
//将错误消息写入事件日志
}   
};
试一试{
QueryRequest请求=null;
string requestBytes=新的StreamReader(context.Request.InputStream.ReadToEnd();
request=requestBytes.FromXml();
书面响应(tryQueryLookup(请求));
}捕获(例外情况除外){
WriterResponse(新的查询响应(“错误”));
}
};
m_HttpAgent=新的HttpAgent(端口,请求解析器);
m_HttpAgent.Start()
这项服务在我们的开发环境中已经运行了好几周了,但是今天我遇到了一个错误,请求返回了一个与之无关的响应——它可能来自对服务器的不同请求,因为请求类型完全不同

我已经设置了一个测试控制台应用程序,它为每种查询类型启动不同的线程,并无限地向服务发出请求。数千个线程成功返回,但最终其中一个线程将始终收到来自服务器的消息,该消息是响应来自其他线程之一的请求类型而生成的。有时,服务器似乎进入故障状态,所有请求都将返回与交叉类型对应的消息

我想知道是否有一些明显的线程问题我没有注意到,或者HTTPListenerContext的行为我没有注意到,因为代码似乎通过在requestParser中使用闭包来隔离每个HTTPListenerContext