[Gtk-sharp-list] Simple threading application that doesn't work with Windows (in Linux it is ok)

Antonio Martínez Álvarez amartinez@atc.ugr.es
Mon, 08 Mar 2004 12:57:18 +0100


This is a multi-part message in MIME format.
--------------050607000808080903030503
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit

Hello.
I'm having lots of problems to make a Gtk# application run ok in Windows.
Sorry, but I've attached the .cs file because it is difficult for me to 
see where the failure is. I have reduced the application to be as small 
as possible and added all the necessary classes inside of the file to 
make the compilation more easy.
I compile it with:  mcs server.cs -r:gtk-sharp -r:gdk-sharp

This is what the application does:
   1.- Shows a Gtk.Window with a button inside.
   2.- When the button is clicked a thread is started. This thread opens 
a TcpListener and listens to Tcp port 8001 in localhost. When a string 
(rece) arrives this is what I do (see 3.) myEvents.Add(rece);
   3.- There is an instance of the class ListWithChangedEvent derived 
from ArrayList which I used to capture the "Changed" event and do 
something (myDebug1).
   4.- This is what I do (myDebug1):

	if rece[0] == '1' then a new instance of CHello (a simple Gtk.Window 
with a button) is shown.
	if rece[0] == 'z' close the thread.

Ok. I have added a comment like this:   //SEE IT:   in 3 places where a 
code appears not to work properly in Windows, these are calls to 
Threads.Init(), Thread.Enter() and Threads.Leave();

I use this event not to do the threads to make something with Gtk# (I 
have heard that it doesn't work).

I promise I have been more than a week studying why it doesn't work.

Can you please help me?

NOTE:
   cliente.cs is a simple client which is connected to Tcp port 8001 and 
sends a simple string. To compile this: mcs server.cs

Thanks in advance.

--
Antonio Martínez

--------------050607000808080903030503
Content-Type: text/plain;
 name="server.cs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="server.cs"

namespace hsm_server {

  using System;
  using System.Net.Sockets;
  using System.Threading;
  using Gdk;
  using Gtk;
  using GtkSharp;
  using MyEvents;
    
  public class Server {
    private TcpListener myListener;
    private int port = 8001;
    public static Gtk.Window app;
    public static CHello win = null;
    public static Button b;
    public static Thread th;
    public static ListWithChangedEvent myEvents = null;
    public static bool listening = true;
	
    public Server () {
      try {
	myListener = new TcpListener (port);
	myListener.Start ();
	Console.WriteLine ("Server Ready - Listining for new Connections ...");
	th = new Thread (new ThreadStart (StartListen));
	th.Start ();
      } 
      catch (Exception e) {
	Console.WriteLine ("Exception Occured :" + e.ToString ());
      }
    }



    /////////////////// MAIN ///////////////
    public static void Main (String[]argv) {
      Application.Init ();
      myEvents = new ListWithChangedEvent();
      myEvents.Changed += new ChangedEventHandler(myDebug1);
      app = new Gtk.Window ("Learning");
      app.DeleteEvent += new DeleteEventHandler (Quit);
      b = new Button ("Press me");
      b.Clicked += new EventHandler (onClick);
      app.Add (b);
      app.ShowAll ();
      Application.Run ();
      Console.WriteLine ("App finished.");
    } 
    
    
    static void onClick (object o, EventArgs a) {
      Server dts = new Server (); 
    } 
  
  
    static void Quit (object o, DeleteEventArgs a) {
      Application.Quit ();
    } 
	

    public static void myDebug1(object o, EventArgs a) {
      Console.WriteLine("myDebug1");

      string cad = (string) myEvents[myEvents.Count -1]; 	
      Console.WriteLine("String received = (" + cad + ")");
      if (cad[0] == '1') {
	Console.WriteLine("Command 1");
	win = new CHello("Hello");
      }
      else if(cad[0] == 'z') {
        listening = false;
      }
      else {
        Console.WriteLine("Unknown command");
      }
    }

  
    public void StartListen () {
      //Threads.Init(); // SEE IT: It doesn't work in Windows
      while (listening == true) {
	Net.Sockets.Socket mySocket = myListener.AcceptSocket ();
	if (mySocket.Connected) {
	  Console.WriteLine ("Client Connected!!");
	  Byte[]receive = new Byte[4];
	  int i;
	  while (listening) {
	    i = mySocket.Receive (receive, receive.Length, 0); 	
	    char[] unwanted = { '\n' };
	    string rece = System.Text.Encoding.ASCII.GetString (receive);
	    //Threads.Enter(); //SEE IT: It doesn't work in Windows
	    myEvents.Add(rece); 
	    //Threads.Leave(); //SEE IT: It doesn't work in windows
	  }
	  Console.WriteLine ("Closing socket...");
	  mySocket.Close ();
	}
      }
    }
  }

  
  /////// A SIMPLE WINDOW WITH A BUTTON /////
  public class CHello:Gtk.Window {
    public Button b1;
    public CHello (string cad):base (cad) {
      b1 = new Button ("Hello");
      this.Add (b1);
      this.ShowAll ();
    }
  }
}


namespace MyEvents {
   using System;
   using System.Collections;

   public delegate void ChangedEventHandler(object sender, EventArgs e);

   public class ListWithChangedEvent: ArrayList {
     public event ChangedEventHandler Changed;

     protected virtual void OnChanged(EventArgs e) {
       if (Changed != null)
         Changed(this, e);
     }

      public override int Add(object value) {
         int i = base.Add(value);
         OnChanged(EventArgs.Empty);
         return i;
      }

      public override object this[int index] {
         set {
            base[index] = value;
            OnChanged(EventArgs.Empty);
         }
      }
   }
}

--------------050607000808080903030503
Content-Type: text/plain;
 name="cliente.cs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="cliente.cs"

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Net.Sockets;

public class clnt {

  public static void Main () {

    TcpClient tcpclnt = new TcpClient ();
      Console.WriteLine ("Connecting.....");
      tcpclnt.Connect ("127.0.0.1", 8001);	
      Console.WriteLine ("Connected");
      Stream stm = tcpclnt.GetStream ();


    while (true){ //AMA
	try {
	  Console.Write ("Enter the string to be transmitted : ");
	  String str = Console.ReadLine ();
	  ASCIIEncoding asen = new ASCIIEncoding ();
	    byte[] ba = asen.GetBytes (str);
	    Console.WriteLine ("Transmitting.....");
	    stm.Write (ba, 0, ba.Length);
	}

	catch (Exception e) {
	  Console.WriteLine ("Error..... " + e.StackTrace);
	}
      }
  }
}

--------------050607000808080903030503--