CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Jun 2007
    Location
    New Delhi
    Posts
    70

    Sharing data between threads

    hi All,
    I am new to c#. I have two threads in my application. One thread (UI thread) takes inputs from user and another thread (worker thread) does some calculation. Now if user clicks stop then worker thread should stop or exit from where it was. But I do not know how to do this in C#. I tried it using static property but no results. If some how I can modify a variable of a class from UI thread and it can be checked in worker thread. Please suggest a way by which I can communicate between 2 threads.

  2. #2
    Join Date
    May 2007
    Location
    Denmark
    Posts
    623

    Re: Sharing data between threads

    I suggest using the BackGroundWorker class, which supports a cancellation feature
    It's not a bug, it's a feature!

  3. #3
    Join Date
    Dec 2007
    Posts
    16

    Re: Sharing data between threads

    well, I worked with a global variable...not static one

    here this is a network snifer works in a working thread while countinuing variable is true...once I click the stop the variable gets false and the working thread stops...
    Code:
            private void button2_Click(object sender, EventArgs e)
            {
                if (continuing)
                {
                    continuing = false;
                    button2.Text = "Start";
                }
    
                else
                {
                    continuing = true;
                    button2.Text = "Stop";
                }
                //IPEndPoint ip = new IPEndPoint(IPAddress.Parse("10.233.125.159"), 80);
                //Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //sock.Bind(ip);
                ////sock.Connect(ip);
                //sock.Listen(2);
                ////sock.Blocking = false;
                //richTextBox1.Text += sock.SendBufferSize.ToString();
                //richTextBox1.Text += sock.ReceiveBufferSize.ToString();
                ////Socket ou = sock.Accept();
                ////richTextBox1.Text += string.Format("{0}", ou.LocalEndPoint.AddressFamily.ToString()+ou.ReceiveBufferSize.ToString()+ou.SendBufferSize.ToString());
                ////ou.Close();
                //sock.Close();
    
    
                if (continuing)
                {
                    string ip1 = @"192.168.0.8";
                    socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
                    byte[] buffer = new byte[2048];
                    //SocketPair socketpair = new SocketPair(socket, buffer);
                    //socket.Blocking = true;
                    socket.Bind(new IPEndPoint(IPAddress.Parse(ip1), 80));
                    socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
                    byte[] IN = new byte[4] { 1, 0, 0, 0 };
                    byte[] OUT = new byte[4];
    
                    int ret_code = socket.IOControl(IOControlCode.ReceiveAll, IN, OUT);
    
                    ret_code = OUT[0] + OUT[1] + OUT[2] + OUT[3];
                    //if (ret_code != 0)
                    //    ret_val = false;
    
                    socket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(Onreceive), null);
    
                    //IPEndPoint h = (IPEndPoint)socket.LocalEndPoint;
                    //IPEndPoint h1 = (IPEndPoint)socket.RemoteEndPoint;
                    //richTextBox1.Text += h.Address.ToString() + "..."+h.Port;
                    //richTextBox1.Text += h1.Address.Address.ToString();
                }
            }
    
            IPHeader ipHeader;
            TCPHeader tcpHeader;
            private void Onreceive(IAsyncResult ar)
            {
                int nReceived = socket.EndReceive(ar);
                ipHeader = new IPHeader(byteData, nReceived);
    
                switch (ipHeader.ProtocolType)
                {
                    case Protocol.TCP:
    
                        tcpHeader = new TCPHeader(ipHeader.Data,              //IPHeader.Data stores the data being 
                            //carried by the IP datagram
                                                            ipHeader.MessageLength);//Length of the data field    
                        //richTextBox1.Text += ipHeader.DestinationAddress.ToString() + "   " + tcpHeader.DestinationPort+Environment.NewLine;
                        richTextBox1.BeginInvoke(new MethodInvoker(UpdateText));
                        //If the port is equal to 53 then the underlying protocol is DNS
                        //Note: DNS can use either TCP or UDP thats why the check is done twice
                        //if (tcpHeader.DestinationPort == "53" || tcpHeader.SourcePort == "53")
                        //{
                        //    TreeNode dnsNode = MakeDNSTreeNode(tcpHeader.Data, (int)tcpHeader.MessageLength);
                        //    rootNode.Nodes.Add(dnsNode);
                        //}
    
                        break;
    
                    case Protocol.UDP:
    
                        //UDPHeader udpHeader = new UDPHeader(ipHeader.Data,              //IPHeader.Data stores the data being 
                        //    //carried by the IP datagram
                        //                                   (int)ipHeader.MessageLength);//Length of the data field                    
    
                        //TreeNode udpNode = MakeUDPTreeNode(udpHeader);
    
                        //rootNode.Nodes.Add(udpNode);
    
                        ////If the port is equal to 53 then the underlying protocol is DNS
                        ////Note: DNS can use either TCP or UDP thats why the check is done twice
                        //if (udpHeader.DestinationPort == "53" || udpHeader.SourcePort == "53")
                        //{
    
                        //    TreeNode dnsNode = MakeDNSTreeNode(udpHeader.Data,
                        //        //Length of UDP header is always eight bytes so we subtract that out of the total 
                        //        //length to find the length of the data
                        //                                       Convert.ToInt32(udpHeader.Length) - 8);
                        //    rootNode.Nodes.Add(dnsNode);
                        //}
    
                        break;
    
                    case Protocol.Unknown:
                        break;
                }
                if (continuing)
                {
                    byteData = new byte[4096];
    
                    //Another call to BeginReceive so that we continue to receive the incoming
                    //packets
                    socket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None,
                        new AsyncCallback(Onreceive), null);
                }
    
            }
            private void UpdateText()
            {
                richTextBox1.Text += ipHeader.DestinationAddress.ToString() + "   " + tcpHeader.SourcePort + Environment.NewLine;
            }

  4. #4
    Join Date
    Apr 2007
    Location
    Florida
    Posts
    403

    Re: Sharing data between threads

    john_avi,

    There is no 'clean' way to cancel a thread on-demand. The only way to cancel threads is to signal for cancellation. When the thread receives the signal, it can then clean up and return out.

    The concept is basically:

    - 2 Threads (Thread A, Thread B)
    - Thread A is your main thread, Thread B is worker thread
    - Thread A starts Thread B
    - User clicks Stop button in Thread A
    - Thread A signals to Thread B to cancel
    - Thread B (polluted with if checks on the cancellation request) receives the signal and when it gets to the next if (cancel), handles the cancellation and returns out

    Personally IMO, cancelling threads in .NET is ugly and primitive, but it works and is the accepted pattern.

    The BackgroundWorker class has a cancellation-like member in its DoWorkEventArgs class, which is passed to each worker thread. You can signal the Cancel (naming?) member from your main thread at any point. The caveat is that your worker thread _MUST_ be polluted with conditional checks for the cancellation member and handle it accordingly.

  5. #5
    Join Date
    Jun 2007
    Location
    New Delhi
    Posts
    70

    Re: Sharing data between threads

    yeah u are right. I had to put a lot of if checks for cancel. Basically I was looking for a way to notify other thread which I am doing using events. I have created a delegate and an event, subscirbe my class object in worker thread for that event and whenever user clicks stop, I raise the event. Actually things are complex in my case because UI application here is an MFC application and working part is a com inerop dll. So things got little bit filthy. But finally I managed to do it.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured