如何在后台TCP服务器和C#主线程中的方法之间进行通信?

时间:2017-10-01 16:22:37

标签: c# json multithreading tcp server

我正在开发一个程序,主程序上有一个UI,后台运行一个TCP服务器。用户通过UI与程序通信,其中信用卡机器处理来自用户的请求并以JSON格式发回结果。一旦TCP服务器收到请求,它就需要通过从主线程调用方法来处理它。 ,转到信用卡机器,JSON格式的结果需要发送到TCP服务器上的调用者。 我在后台请求和主线程中提供响应的方法之间的通信方面遇到了困难。 我对每个请求进行Enquque,然后调用一个方法FireTransaction(),该方法与信用卡终端通信到Dequque并处理每个请求。 FireTransaction()将一个JSON对象分配给outJ变量,它应该是响应。但是请求陷入循环,而信用卡正在处理它。我该如何解决这个问题?

 private void CallServer()
    {
        try
        {                
            int port = 7001;
            IPAddress serverAddress = IPAddress.Parse("127.0.0.1");
            TcpListener listener = new TcpListener(serverAddress, port);

            listener.Start();

            while (true)
            {
                TcpClient client = listener.AcceptTcpClient();
                StreamReader sr = new StreamReader(client.GetStream());
                StreamWriter sw = new StreamWriter(client.GetStream());

                string request = sr.ReadLine(); 
                string[] tokens = request.Split(' ');
                string reqProcess = tokens[1];

                if (!cq.Contains(reqProcess))
                {
                    cq.Enqueue(reqProcess);
                    **Dispatcher.Invoke(new Action(() => { FireTransaction(); }));**

                    Thread.Sleep(17000);
                        if (!string.IsNullOrEmpty(outJ))
                        { System.Text.Encoding.ASCII.GetBytes(outJ);
                            sw.WriteLine("HTTP/1.0 200 OK\n");
                            sw.Write(outJ);
                        }                      
                }                                          
                client.Close();
            }               
        }

private async void FireTransaction()
    {
        double valAmount;
        string result;
        if (cq.TryDequeue(out result))
        {
            if (result != null)
            {
                string[] command = result.Split(new[] { "&" }, StringSplitOptions.None);
                outJ = string.Empty;
                valAmount = Convert.ToDouble(command[1].ToString());
                outJ = await CreditCards.DoCredit(valAmount);
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

你应该在一个单独的线程中处理传入请求的循环内容(每个传入的连接应该在一个单独的线程中处理)。

对于FireTransaction,您可以传递一个WaitHandle ManualResetEvent,例如FireTransaction(或只是一个对象,如果您需要),它已在处理线程中创建。
在用句柄作为参数调用Thread.Sleep之后,等待手柄发出信号 - 在FireTransaction内你发布'完成所有处理后的信号。这样你就可以摆脱FireTransaction的东西......

并且您的import pickle from rangedict import RangeDict rngdct = RangeDict() rngdct[(1, 9)] = \ {"Type": "A", "Series": "1"} rngdct[(10, 19)] = \ {"Type": "B", "Series": "1"} with open('rangedict.pickle', 'wb') as f: pickle.dump(rngdct, f) 方法应返回处理结果,而不是设置类(或全局)变量。