优化tcp / IP端口侦听器C#

时间:2018-01-08 15:22:37

标签: c# sockets asynchronous task

我正在创建一个控制台应用程序来监听tcp / IP端口并将数据保存到sql server并且它工作正常但是 SQLServer服务占用CPU使用率的99% 我的服务器配置 窗口服务器2012 - intel xeon - 16G Ram 平均数据2包/秒 代码

public class StateObject{

public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();}



public class AsynchronousSocketListener{
    public static ManualResetEvent allDone = new ManualResetEvent(false);


public AsynchronousSocketListener()
{
}

public static void StartListening()
{
    // Data buffer for incoming data.
    byte[] bytes = new Byte[1024];

    // Establish the local endpoint for the socket.
    // The DNS name of the computer
    // running the listener is "host.contoso.com".
    IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
    IPAddress ipAddress = ipHostInfo.AddressList[0];
    IPAddress local = IPAddress.Parse("xxx.xxx.xx.xxx");
    IPEndPoint localEndPoint = new IPEndPoint(ipAddress, xxxx);

    // Create a TCP/IP socket.
    Socket listener = new Socket(AddressFamily.InterNetwork,
        SocketType.Stream, ProtocolType.Tcp);

    // Bind the socket to the local endpoint and listen for incoming connections.
    try
    {
        listener.Bind(localEndPoint);
        listener.Listen(100);

        while (true)
        {
            // Set the event to nonsignaled state.
            allDone.Reset();
            // Start an asynchronous socket to listen for connections.
            Console.WriteLine("Waiting for a connection...");
            listener.BeginAccept(
                new AsyncCallback(AcceptCallback),
                listener);
            Console.WriteLine("Got Connection");
            // Wait until a connection is made before continuing.
            allDone.WaitOne();
        }

    }
    catch (Exception e)
    {
        Console.WriteLine("Error in connection");
    }


}

public static void AcceptCallback(IAsyncResult ar)
{
    Console.WriteLine("Start Call");
    // Signal the main thread to continue.
    allDone.Set();

    // Get the socket that handles the client request.
    Socket listener = (Socket)ar.AsyncState;
    Socket handler = listener.EndAccept(ar);

    // Create the state object.
    StateObject state = new StateObject();

    state.workSocket = handler;
    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
        new AsyncCallback(ReadCallback), state);
}

public static void ReadCallback(IAsyncResult ar)
{
    String content = String.Empty;

    // Retrieve the state object and the handler socket
    // from the asynchronous state object.

    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    // Read data from the client socket. 
    int bytesRead = handler.EndReceive(ar);
    if (bytesRead > 0)
    {
        // There  might be more data, so store the data received so far.
        state.sb.Append(Encoding.ASCII.GetString(
            state.buffer, 0, bytesRead));

        // Check for end-of-file tag. If it is not there, read 
        // more data.
        content = state.sb.ToString();

        try
        {

            SaveData(content);
            // Not all data received. Get more.
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReadCallback), state);
            // }
        }
        catch (Exception e)
        {

            // Console.WriteLine(e.ToString());
        }
    }
}



 static async Task<List<int>> GetGeo(int CarID, int BranchID, int CompID)
{

    List<int> Geos = new List<int>();
    List<int> RejectedGeos = new List<int>();
    using (SqlConnection conn = new SqlConnection(ConnStr))

    {

        conn.Open();

        using (SqlCommand cmd = conn.CreateCommand())
        {
            //SQL Server Query
        }
    }

    return Geos;


}

static Task CloseAlarm(double Lat, double Lng, string Date, double Speed, int CarID, double MaxSpeed, int GeoID, int AlarmType, int CompID, List<int> CurrGeos)
{
    Task t = new Task(() =>
    {
        string ConnStr = "Data Source =.; Initial Catalog = GPS_Tracking;Integrated Security = True";
        try
        {
            using (SqlConnection conn = new SqlConnection(ConnStr))
            {
                conn.Open();
                using (SqlCommand comm = new SqlCommand())
                {

                        //SQl Save Command
                }
            }
        }
        catch { }
    });

    t.Start();

    return t;
}
static Task insertAlarm(double Lat, double Lng, string Date, double Speed, int CarID, double MaxSpeed, int GeoID, int AlarmType, int CompID)
{

    Task t = new Task(() =>
    {
        string ConnStr = "Data Source =.; Initial Catalog = GPS_Tracking;Integrated Security = True";
        try
        {
            using (SqlConnection conn = new SqlConnection(ConnStr))
            {
                conn.Open();
                using (SqlCommand comm = new SqlCommand("Select * from T_GeoFence2 where isdeleted=0 and CompanyID=" + CompID, conn))
                {
                    // SQL Save Command
                }
            }

        }
        catch (Exception ex) { }
    });

    t.Start();

    return t;
}
static Task SaveAlarms(double Lat, double Lng, string Date, double Speed, int CarID, int BranchID, int CompID, double MaxSpeed)
{
    Task t = new Task(() =>
    {
        List<int> Geos = GetGeo(CarID, BranchID, CompID).Result;
        List<int> CurrGeos = new List<int>();
        bool saveSpeedAlarm = true;

        string point = "Point(" + Lat + " , " + Lng + ",4326)";

        string ConnStr = "Data Source =.; Initial Catalog = GPS_Tracking;Integrated Security = True";
        try
        {
            using (SqlConnection conn = new SqlConnection(ConnStr))
            {
                conn.Open();
                using (SqlCommand comm = new SqlCommand())
                {

                       // SQL Check  

                    if (MaxSpeed < Speed && saveSpeedAlarm)
                    {
                        insertAlarm(Lat, Lng, Date, Speed, CarID, MaxSpeed, 0, 2, CompID);

                    }
                    else
                    {
                        CloseAlarm(Lat, Lng, Date, Speed, CarID, MaxSpeed, 0, 2, CompID, new List<int>());

                    }
                    CloseAlarm(Lat, Lng, Date, Speed, CarID, MaxSpeed, 0, 1, CompID, CurrGeos);

                }

            }
        }

        catch (Exception ex) { }

    });

    t.Start();

    return t;
}

private static void Send(Socket handler, String data)
{
    // Convert the string data to byte data using ASCII encoding.
    byte[] byteData = Encoding.ASCII.GetBytes(data);

    // Begin sending the data to the remote device.
    handler.BeginSend(byteData, 0, byteData.Length, 0,
        new AsyncCallback(SendCallback), handler);
}

private static void SendCallback(IAsyncResult ar)
{
    try
    {
        // Retrieve the socket from the state object.
        Socket handler = (Socket)ar.AsyncState;

        // Complete sending the data to the remote device.
        int bytesSent = handler.EndSend(ar);
        // Console.WriteLine("Sent {0} bytes to client.", bytesSent);

        handler.Shutdown(SocketShutdown.Both);
        handler.Close();

    }
    catch (Exception e)
    {
        //  Console.WriteLine(e.ToString());
    }
}


private static Task SaveData(string data)
{

    Task t = new Task(() =>
    {
           using (SqlConnection conn = new SqlConnection(ConnStr))

                {
                    conn.Open();
                    using (SqlCommand cmd = conn.CreateCommand())
                    {
                        //More SQL
                    }
                }

                              ///////Save Arabic Tracking////////////////////
              SaveTrackingAR(latmap, lngmap, IMEI, myDate, Speed, SafeArea, DangerArea, CarID, distance);
                                ////////////////////////////////////
                                ///////////////Save English Tracking ////////////////////
             SaveTrackingEN(latmap, lngmap, IMEI, myDate, Speed, SafeArea, DangerArea, CarID, distance);
                                ////////////////////////////////////
           SaveAlarms(latmap, lngmap, myDate, Speed, CarID, CarBranch, CarCompany, CarMaxSpeed);





    });

    t.Start();

    return t;
}
private static Task SaveTrackingAR(double latmap, double lngmap, string IMEI, string myDate, double Speed, int SafeArea, int DangerArea, int CarID, double distance)
{
    Task t = new Task(() =>
    {
        // Some Long Running Code ..
        using (SqlConnection conn = new SqlConnection(ConnStr))

        {
            conn.Open();

            using (SqlCommand cmd = conn.CreateCommand())
            {

                // SQL Data 

                    if (dtLoc.Rows.Count > 0)
                    {

                    }
                    else
                    {

                        string locationsRequest = CreateRequest(latmap, lngmap);
                        // XmlDocument locationsResponse = MakeRequest(locationsRequest);
                        XDocument xmlDoc = XDocument.Load(locationsRequest);
            // Handle XMl

            }
        }
    });

    t.Start();

    return t;
}
private static Task SaveTrackingEN(double latmap, double lngmap, string IMEI, string myDate, double Speed, int SafeArea, int DangerArea, int CarID, double distance)
{
    Task t = new Task(() =>
    {
        // Some Long Running Code ..

        using (SqlConnection conn = new SqlConnection(ConnStr))

        {
            conn.Open();

            using (SqlCommand cmd = conn.CreateCommand())
            {

              // SQl Data
                if (dtLoc.Rows.Count > 0)
                {

                }

                else
                {


                        string locationsRequest = CreateRequestEN(latmap, lngmap);
                        // XmlDocument locationsResponse = MakeRequest(locationsRequest);
                        XDocument xmlDoc = XDocument.Load(locationsRequest);


            }
        }
    });

    t.Start();

    return t;
}


private static string CreateRequest(double latmap, double lngmap)
{
    return "http://maps.googleapis.com/maps/api/geocode/xml?latlng=" + latmap + "," + lngmap + "&sensor=true&language=ar";
}
private static string CreateRequestEN(double latmap, double lngmap)
{
    return "http://maps.googleapis.com/maps/api/geocode/xml?latlng=" + latmap + "," + lngmap + "&sensor=true&language=en";
}
public static XmlDocument MakeRequest(string requestUrl)
{
    try
    {
        HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
        HttpWebResponse response = request.GetResponse() as HttpWebResponse;

        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(response.GetResponseStream());
        return (xmlDoc);

    }
    catch (Exception e)
    {
        // Console.WriteLine(e.Message);

        // Console.Read();
        return null;
    }
}
public static int Main(String[] args)
{

    StartListening();
    return 0;
}

我使用任务试图减少cpu消耗 我有很多sql查询和数据保存但它是必需的 我可以在我的案例中使用哪些优化方法(任务 - 异步 - 等) 但是我的一些查询依赖于彼此 我必须从数据库检查是否保存警报,如果是,则不再保存 如果没有保存

谢谢

0 个答案:

没有答案