G
Guest
Hi,
I encountered a problem wich is a big mystery to me and my colleagues.
So this is the application I wrote:
- A C# Client application for Windows CE .NET CompactFramework which
connects to a server via TcpClient and sends a "Next"-package to tell the
server to send data
- A C# Server application (WinXP SP2) which waits for a "Next" or "Stop"
package (TcpListener) and then generates some numbers to send to the client.
- Basically the whole application is just some kind of proof-of-concept,
it's not a huge thing.
- I use the VS.NET (2003) Windows CE emulator to run the wince client app
This is my problem:
The whole data transfer works very well and quite fast, until I move the
mouse into the WinCE-application window of the WincE Emulator. Then the data
transfer slows down until it totally stops. I have no explanation for that,
because I didn't write any event listeners. How can the program stop when I
move the _MOUSE_ even though I don't have a single line of code that refers
to mouse movement?
I traced down the problem to the following: When I uncomment the line of
code which puts the responseData into a label, the program will not stop. You
can check yourself by commenting / uncommenting the line "label1.Text =
responseData;" in the client application. (You will notice that I even put
this line into a separate thread, because then you will see that the Thread
dies, not the application.)
This is my concluding question:
Is it not possible to access the window elements of the control thread out
of a separate thread?
So here is the code, you can try youself and see if you have the same
problem (just move the mouse in the client window, while the connection is
active):
Client application:
And this is the server application:
Can anybody help me please? ... otherwise I become desperate ...
Thank you in advance!
BTW: Sorry for the German comments - I'm German. But I guess the code is
quite obvious.
I encountered a problem wich is a big mystery to me and my colleagues.
So this is the application I wrote:
- A C# Client application for Windows CE .NET CompactFramework which
connects to a server via TcpClient and sends a "Next"-package to tell the
server to send data
- A C# Server application (WinXP SP2) which waits for a "Next" or "Stop"
package (TcpListener) and then generates some numbers to send to the client.
- Basically the whole application is just some kind of proof-of-concept,
it's not a huge thing.
- I use the VS.NET (2003) Windows CE emulator to run the wince client app
This is my problem:
The whole data transfer works very well and quite fast, until I move the
mouse into the WinCE-application window of the WincE Emulator. Then the data
transfer slows down until it totally stops. I have no explanation for that,
because I didn't write any event listeners. How can the program stop when I
move the _MOUSE_ even though I don't have a single line of code that refers
to mouse movement?
I traced down the problem to the following: When I uncomment the line of
code which puts the responseData into a label, the program will not stop. You
can check yourself by commenting / uncommenting the line "label1.Text =
responseData;" in the client application. (You will notice that I even put
this line into a separate thread, because then you will see that the Thread
dies, not the application.)
This is my concluding question:
Is it not possible to access the window elements of the control thread out
of a separate thread?
So here is the code, you can try youself and see if you have the same
problem (just move the mouse in the client window, while the connection is
active):
Client application:
Code:
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace AR_Client
{
/// <summary>
/// Zusammenfassung für Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.TextBox tb_Server;
private System.Windows.Forms.TextBox tb_Request;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Label label1;
private bool running = false;
private System.Windows.Forms.TextBox textBox1;
private String res;
static String responseData = "";
public Form1()
{
//
// Erforderlich für die Windows Form-Designerunterstützung
//
InitializeComponent();
this.res = this.tb_Request.Text;
//
// TODO: Konstruktorcode hinter dem
InitializeComponent-Aufruf hinzufügen
//
}
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
#region Vom Windows Form-Designer generierter Code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert
werden.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.tb_Server = new System.Windows.Forms.TextBox();
this.tb_Request = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.textBox1 = new System.Windows.Forms.TextBox();
//
// button1
//
this.button1.Location = new System.Drawing.Point(8, 8);
this.button1.Size = new System.Drawing.Size(104, 20);
this.button1.Text = "Start";
this.button1.Click += new
System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(144, 8);
this.button2.Text = "Stop";
this.button2.Click += new
System.EventHandler(this.button2_Click);
//
// button3
//
this.button3.Location = new System.Drawing.Point(224, 8);
this.button3.Text = "Quit";
this.button3.Click += new
System.EventHandler(this.button3_Click);
//
// tb_Server
//
this.tb_Server.Location = new System.Drawing.Point(8, 32);
this.tb_Server.Text = "172.17.31.34";
//
// tb_Request
//
this.tb_Request.Location = new System.Drawing.Point(8, 56);
this.tb_Request.Text = "Next";
this.tb_Request.TextChanged += new
System.EventHandler(this.tb_Request_TextChanged);
//
// label1
//
this.label1.Location = new System.Drawing.Point(144, 48);
this.label1.Size = new System.Drawing.Size(96, 16);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(136, 64);
this.textBox1.Text = "";
this.FormBorderStyle =
System.Windows.Forms.FormBorderStyle.FixedToolWindow;
//
// Form1
//
this.ClientSize = new System.Drawing.Size(306, 90);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.label1);
this.Controls.Add(this.tb_Request);
this.Controls.Add(this.tb_Server);
this.Controls.Add(this.button1);
this.Controls.Add(this.button2);
this.Controls.Add(this.button3);
this.MaximizeBox = false;
this.Text = "TCP/IP Client";
}
#endregion
/// <summary>
/// Der Haupteinstiegspunkt für die Anwendung.
/// </summary>
static void Main()
{
Application.Run(new Form1());
}
private void Connect()
{
try
{
if (this.running)
{
// Objekte erstellen, damit nicht der ganze
Speicher vom PDA verschwendet wird
Int32 port = 81;
TcpClient client;
Byte[] data;
NetworkStream stream;
String con = tb_Server.Text;
while (this.running)
{
// MessageBox.Show("1");
client = new TcpClient(con, port );
// Die Überprüfung mach ich erst hier drinnen
(könnte ja auch schon beim Stop-Button sein), damit
// der Server noch ein Stop empfängt und
ebenfalls aufhört.
// MessageBox.Show("2");
if (res == "Stop")
running = false;
// MessageBox.Show("3");
data = new byte[4];
data[0] = 78;
data[1] = 101;
data[2] = 120;
data[3] = 116;
// MessageBox.Show("4");
stream = client.GetStream();
stream.Write(data, 0, 4);
// MessageBox.Show("6");
data = new Byte[256];
// MessageBox.Show("8");
Int32 bytes = stream.Read(data, 0, data.Length);
// MessageBox.Show("9");
responseData =
System.Text.Encoding.ASCII.GetString(data, 0, bytes);
// MessageBox.Show("10");
// this.textBox1.Text = responseData;
// Close everything.
// MessageBox.Show("11");
stream.Close();
client.Close();
client = null;
// Thread.Sleep(10);
}
}
}
catch (ArgumentNullException e)
{
MessageBox.Show("ArgumentNullException: "+ e.ToString());
}
catch (SocketException e)
{
MessageBox.Show("SocketException: "+ e.ToString());
}
catch (Exception e)
{
MessageBox.Show("Exception: "+e.ToString());
}
}
private void writeRespData()
{
while (running)
{
// label1.Text = responseData;
// MessageBox.Show(responseData);
Thread.Sleep(10);
}
}
private void button1_Click(object sender, System.EventArgs e)
{
running = true;
tb_Request.Text = "Next";
Thread clientThread = new Thread(new ThreadStart(Connect));
clientThread.Start();
Thread respDataThread = new Thread(new
ThreadStart(writeRespData));
respDataThread.Start();
}
private void button2_Click(object sender, System.EventArgs e)
{
tb_Request.Text = "Stop";
}
private void button3_Click(object sender, System.EventArgs e)
{
this.Close();
}
private void tb_Request_TextChanged(object sender,
System.EventArgs e)
{
this.res = this.tb_Request.Text;
}
}
}
And this is the server application:
Code:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace AR_Server
{
/// <summary>
/// Zusammenfassung für Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox tb_IP;
private System.Windows.Forms.TextBox tb_Msg;
private System.Windows.Forms.TextBox tb_Port;
private Thread serverThread;
private static bool running = false;
private System.Windows.Forms.RichTextBox richTextBox1;
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Erforderlich für die Windows Form-Designerunterstützung
//
InitializeComponent();
//
// TODO: Fügen Sie den Konstruktorcode nach dem Aufruf von
InitializeComponent hinzu
//
}
/// <summary>
/// Die verwendeten Ressourcen bereinigen.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Vom Windows Form-Designer generierter Code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert
werden.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.tb_IP = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.button2 = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.tb_Port = new System.Windows.Forms.TextBox();
this.button3 = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.tb_Msg = new System.Windows.Forms.TextBox();
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(248, 24);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "Set";
this.button1.Click += new
System.EventHandler(this.button1_Click);
//
// tb_IP
//
this.tb_IP.Location = new System.Drawing.Point(32, 24);
this.tb_IP.Name = "tb_IP";
this.tb_IP.TabIndex = 1;
this.tb_IP.Text = "172.17.31.34";
//
// label1
//
this.label1.Location = new System.Drawing.Point(8, 24);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(24, 16);
this.label1.TabIndex = 2;
this.label1.Text = "IP:";
//
// button2
//
this.button2.Location = new System.Drawing.Point(192, 16);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(72, 32);
this.button2.TabIndex = 3;
this.button2.Text = "Start Server";
this.button2.Click += new
System.EventHandler(this.button2_Click);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.tb_Port);
this.groupBox1.Controls.Add(this.button3);
this.groupBox1.Controls.Add(this.tb_IP);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Controls.Add(this.button2);
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Location = new System.Drawing.Point(8, 8);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(328, 56);
this.groupBox1.TabIndex = 4;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Admin";
//
// tb_Port
//
this.tb_Port.Location = new System.Drawing.Point(140, 24);
this.tb_Port.Name = "tb_Port";
this.tb_Port.Size = new System.Drawing.Size(40, 20);
this.tb_Port.TabIndex = 5;
this.tb_Port.Text = "81";
//
// button3
//
this.button3.Location = new System.Drawing.Point(272, 16);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(48, 32);
this.button3.TabIndex = 4;
this.button3.Text = "Quit";
this.button3.Click += new
System.EventHandler(this.button3_Click);
//
// label2
//
this.label2.Font = new System.Drawing.Font("Microsoft Sans
Serif", 15.75F, System.Drawing.FontStyle.Bold,
System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.label2.Location = new System.Drawing.Point(130, 18);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(8, 24);
this.label2.TabIndex = 2;
this.label2.Text = ":";
//
// groupBox2
//
this.groupBox2.Controls.Add(this.tb_Msg);
this.groupBox2.Controls.Add(this.button1);
this.groupBox2.Location = new System.Drawing.Point(8, 72);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(328, 56);
this.groupBox2.TabIndex = 5;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Application";
//
// tb_Msg
//
this.tb_Msg.Location = new System.Drawing.Point(16, 24);
this.tb_Msg.Name = "tb_Msg";
this.tb_Msg.Size = new System.Drawing.Size(224, 20);
this.tb_Msg.TabIndex = 1;
this.tb_Msg.Text = "Test";
//
// richTextBox1
//
this.richTextBox1.Location = new System.Drawing.Point(8, 144);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.ScrollBars =
System.Windows.Forms.RichTextBoxScrollBars.ForcedBoth;
this.richTextBox1.Size = new System.Drawing.Size(328, 96);
this.richTextBox1.TabIndex = 6;
this.richTextBox1.Text = "";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(344, 285);
this.Controls.Add(this.richTextBox1);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.Name = "Form1";
this.Text = "AR Server";
this.groupBox1.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private void button3_Click(object sender, System.EventArgs e)
{
if (running) // dem Thread bescheid sagen, daß er aufhören
soll
running = false;
Application.Exit();
}
private void StartServer()
{
long count = 0;
try
{
Int32 port = Convert.ToInt32(tb_Port.Text);
IPAddress localAddr = IPAddress.Parse(tb_IP.Text);
TcpListener server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[256];
// Enter the listening loop.
while(running)
if (server.Pending())
{
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket()
here.
TcpClient client = server.AcceptTcpClient();
String data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
// Loop to receive all the data sent by the
client.
while(((i = stream.Read(bytes, 0,
bytes.Length))!=0) && (running))
{
// Translate data bytes to a ASCII string.
data =
System.Text.Encoding.ASCII.GetString(bytes, 0, i);
// Process the data sent by the client.
string response = String.Empty;
// schickt Default-Meldung, daß er dieses Datenpaket nicht zuordnen
kann
switch (data)
{
default:
response = "Unknown";
break;
case "Next":
response = tb_Msg.Text;
// schickt das, was in der TextBox steht
break;
case "Stop":
response = "Stop";
running = false;
break;
}
byte[] msg = new byte[response.Length];
for (int i2 = 0; i2<response.Length; i2++)
msg[i2] =
Convert.ToByte(response[i2]);
// Send back a response.
stream.Write(msg, 0, msg.Length);
count++;
if (richTextBox1.Lines.Length > 1000)
richTextBox1.Text =
count.ToString()+": rcv "+data+" resp "+response+" \n";
else
richTextBox1.Text =
count.ToString()+": rcv "+data+" resp "+response+" \n"+richTextBox1.Text;
// Zufallsdaten fürs Netzwerk erfinden
Random test = new
Random(Environment.TickCount); // dieses Environment.TickCount dient nur der
Initialisierung
int teiler = test.Next(100,2000);
tb_Msg.Text = teiler.ToString();
// Thread.Sleep(10); // Das hier ist nur
da, um die Prozessorlast zu senken, damit der nicht die ganze Zeit die
Schleife mit voller Power durchläuft.
}
// Shutdown and end connection
stream.Close();
client.Close();
}
server.Stop();
}
catch(SocketException e)
{
MessageBox.Show("SocketException: "+e.ToString());
}
catch(Exception e)
{
MessageBox.Show("Exception: "+e.ToString());
}
}
private void button2_Click(object sender, System.EventArgs e)
{
if (button2.Text=="Start Server")
{
running = true;
serverThread = new Thread(new ThreadStart(StartServer));
serverThread.Start();
button2.Text = "Stop Server";
}
else
{
running = false;
// if (serverThread.IsAlive)
// serverThread.Abort(0);
button2.Text = "Start Server";
}
}
private void button1_Click(object sender, System.EventArgs e)
{
}
}
}
Can anybody help me please? ... otherwise I become desperate ...
Thank you in advance!
BTW: Sorry for the German comments - I'm German. But I guess the code is
quite obvious.