Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 7 của 7
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Vấn đề là em cần biết nguyên nhân lỗi và cách khắc phục, vì nếu từng client bị ngắt kết nối thì chương trình chạy không sao cả.

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Mình không thấy code của hàm processpacket.them_nick(packet,false); mình đọc thông báo thì có thể là do server bạn dùng một connect đến data mà trong hàm processpacket.them_nick(packet,false); của bạn khi client đóng kết nối thì bạn cũng đóng connect nên các sự kiện khác của các client khác không thực hiện được

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trích dẫn Gửi bởi thansautk
    Mình không thấy code của hàm processpacket.them_nick(packet,false); mình đọc thông báo thì có thể là do server bạn dùng một connect đến data mà trong hàm processpacket.them_nick(packet,false); của bạn khi client đóng kết nối thì bạn cũng đóng connect nên các sự kiện khác của các client khác không thực hiện được
    trong hàm "processpacket.them_nick(packet,false);" chỉ là thực thi câu lệnh sql thoai ko có gì cả

  5. #5
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    Bị lỗi thực hiện câu lệnh update khi nhiều luồng cùng chạy câu lệnh cùng một lúc

    Có thể tiêu để của em chưa rõ ràng.
    Em xin trình bày vấn đề của em như sau.
    Em có làm 1 cái file server(như vậy cần chạy đa luồng để cho các client kết nối tới)

    Mã:
    public void connect()        {                        string packet = "";            try            {                Console.WriteLine("Da chay luong moi");                //chạy server                server.Start();                Console.WriteLine("Da chay server, dang cho client connect .....");                client = server.AcceptTcpClient();                Console.WriteLine(client.Client.RemoteEndPoint.ToString() + " ket noi toi");                //có client kết nối tới thì tạo 1 luồng mới để cho 1 client khác kết nối tới                Thread objthread = new Thread(new ThreadStart(connect));                objthread.Start();                 while (true)                {                    //đọc packet từ client đến server                    StreamReader sr = new StreamReader(client.GetStream());                    StreamWriter wr = new StreamWriter(client.GetStream());                    packet = sr.ReadLine();                    Console.WriteLine(client.Client.RemoteEndPoint.ToString() + " gui packet: " + packet);                    // gửi lại packet đến client                    process(wr, packet);                    if (client.Connected == false)                    {                        try                        {                            Console.WriteLine(client.Client.RemoteEndPoint.ToString() + " ngat ket noi");                        }                        catch                        { }                        processpacket.them_nick(packet,false);                        client.Close();                        objthread.Abort();                        objthread.Join();                        return;                    }                }            }            catch (System.Exception ex)            {                Thread.Sleep(500);                try                {                    Console.WriteLine(client.Client.RemoteEndPoint.ToString() + " ngat ket noi");                }                catch                { }                processpacket.them_nick(packet, false);                client.Close();                return;            }        }
    Còn đây là lớp thực thi command sql

    Mã:
    public class library    {        static SqlConnection sqlcon;        static SqlDataAdapter sqlad;        static DataSet objds;                public static void getconnectionstring()        {            try            {                sqlcon = new SqlConnection(@"Data Source=.\SQL_EXPRESS;AttachDbFilename='C:\Users\NguyenTuan\Documents\Visual Studio 2010\Projects\Project2Q6\Project2Q6\App_Data\Project2Q6.mdf';Integrated Security=True;Connect Timeout=30;User Instance=True");                            }           catch            {             }                    }        public static void getconnectionstring(string strnameconnect)        {            try            {                sqlcon = new SqlConnection(@"Data Source=.\SQL_EXPRESS;AttachDbFilename='C:\Users\NguyenTuan\Documents\Visual Studio 2010\Projects\Project2Q6\Project2Q6\App_Data\billing.mdf';Integrated Security=True;Connect Timeout=30;User Instance=True");            }            catch            {             }        }        /// <summary>        /// Hàm này thực thi một câu lệnh SELECT        /// </summary>        /// <param name="strcom">Là chuỗi SqlCommand</param>        /// <returns>Hàm này trả về một DataSet</returns>        public static DataSet execommand(SqlCommand strcom)        {            // kết nối            getconnectionstring();            // mở kết nối            sqlcon.Open();            // thiết lập command sẽ sử dụng kết nối            strcom.Connection = sqlcon;            // tạo Adapter lấy dữ liệu            sqlad = new SqlDataAdapter();            // Adapter sẽ lấy dữ liệu từ command trên            sqlad.SelectCommand = strcom;            // tạo Dataset để truyền dữ liệu từ Adapter            objds = new DataSet();            // chạy command            int countline = strcom.ExecuteNonQuery();            // đổ dữ liệu từ Adapter vào Dataset            sqlad.Fill(objds);            // đóng kết nối            sqlcon.Close();            return objds;        }        /// <summary>        /// Hàm này thực hiện câu lệnh UPDATE, INSERT, DELETE        /// </summary>        /// <param name="strcom">Là chuỗi SqlCommand</param>        /// <param name="typecommand">Gồm các tham số update, insert, delete</param>        /// <returns></returns>        public static int execommand(SqlCommand strcom, string typecommand)        {            //tạo 1 một transaction            SqlTransaction transaction;            int countline = 0;            try            {                // kết nối                getconnectionstring();                // mở kết nối                sqlcon.Open();                //bắt đầu 1 transaction                transaction = sqlcon.BeginTransaction();                strcom.Transaction = transaction;                // thiết lập command sẽ sử dụng kết nối                strcom.Connection = sqlcon;                // tạo Adapter lấy dữ liệu                sqlad = new SqlDataAdapter();                // Adapter sẽ lấy dữ liệu từ command trên                if (typecommand == "update")                {                    sqlad.UpdateCommand = strcom;                }                else if (typecommand == "insert")                {                    sqlad.InsertCommand = strcom;                }                else if (typecommand == "delete")                {                    sqlad.DeleteCommand = strcom;                }                // chạy command                try                {                    countline = strcom.ExecuteNonQuery();                    transaction.Commit();                }                catch (SqlException ex)                {                    transaction.Rollback();                }                // đóng kết nối                sqlcon.Close();            }            catch (SqlException ex)            {            }            return countline;        }           }
    Mọi việc đều ok khi các client kết nối tới
    Như trên code của em mỗi khi client ngắt kết nối thì ứng dụng sẽ gọi hàm processpacket.them_nick(packet,false);
    Hàm này cũng ko có vấn đề gì cả nếu như tại 1 thời điểm chỉ có 1 client bị ngắt kết nối(bị ngắt kết nối vì 1 lý do nào đó như bị kill, rớt mạng).
    Nhưng nếu như các client "cùng 1 lúc" ngắt kết nối thì sẽ bị lỗi
    (Ngày hôm qua thì bị lỗi ở đoạn) countline = strcom.ExecuteNonQuery(); với thông báo lỗi là "ExecuteNonQuery requires an open and available Connection. The connection's current state is closed."
    Còn hôm nay khi các client bị ngắt kết nối cùng 1 lúc thì bị lỗi ở đoạn
    transaction = sqlcon.BeginTransaction(); với thông báo là "Invalid operation. The connection is closed."
    Có ai biết cách khách phục không giúp em với

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Hôm nay đọc lại code của bạn thì mình có để ý một số điểm không biết có đúng không?

    Hệ thống của bạn là chạy multithread và bạn chỉ sử dụng một biến connect.khi các client thực hiện hầu như cùng một lúc thì lúc đó biến sqlcon trong connect của bạn bị sử dụng chung, do vậy dẫn đến tình trạng như bạn thông báo.

    Hướng giải quyết như sau:
    Cách 1. bạn để mỗi một client khi kết nối đến server sẽ sử dụng riêng một biến connect, như vậy sẽ không xảy ra xung đột.
    Cách 2. trong hàm execommand của bạn thì không tạo kết nối và đóng kết nối nữa. Bạn sẽ tạo kết nối 1 lần và sử dụng đến khi nào close sever thì mới đóng kết nối.cách này sẽ làm giải thời gian cho server vì mỗi lần thực hiện lệnh đều connect lại sẽ mất thời gian đến data dặt ở máy khác.

    Bạn thử làm theo một trong hai cách trên xem sao?

  7. #7
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Nếu cách của thansautk vẫn bị lỗi thì có thể do, nhiều thread cùng truy cập 1 tài nguyên nên dẫn đến lỗi. Nếu bị lỗi này hãy sử dụng lock để thực hiện insert. Tính năng lock là khi 1 thread chiếm tài nguyên thì thread khác đợi thread kia chạy xong mới được thực thi.

    Mã:
    static Object thisLock = new Object();lock (thisLock){    // Lock xử lý khi 1 thread chiếm vùng này}
    Trong chuơng trình của bạn hãy thực hiện như sau

    Mã:
    lock (thisLock){    processpacket.them_nick(packet,false);}
    Nhớ khai báo đoạn này là 1 biến thành viên trong class:

    Mã:
    static Object thisLock = new Object();

 

 

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •