|
Hy guys ! i've been trying to write up classes for a server and a client using sockets, i'm having a bit of a problem with the server : whenever i try to read incoming messages or send messages i get "Object reference not set to an instance of an object" error, this is because my streamWriter/Reader is null. My problem is that i can't figure out why they are null!? when i instance them there are no problems, but when i invoke their mothods they're null , does anybody have any ideeas ?
some code snippets might help to clear this up :
the declarations :
class Server
{
private TcpListener listner;
private Socket socketForClients;
private System.IO.StreamReader messageReader;
private System.IO.StreamWriter messageWriter;
the instantianion :
public void startSever()
{
listner.Start();
socketForClients = listner.AcceptSocket();
if (socketPentruClienti.Connected == true)
{
try
{
NetworkStream networkStream = new NetworkStream(socketForClients);
System.IO.StreamWriter messageWriter = new System.IO.StreamWriter(networkStream);
System.IO.StreamReader messageReader = new System.IO.StreamReader(networkStream);
}
catch (Exception eNetworkStream)
{
System.Windows.Forms.MessageBox.Show("EROARE : eroare la network stream\nEXCEPTIE : "+eNetworkStream.Message);
}
}
}
the invoking :
public void write(string message)
{
try
{
messageWriter.WriteLine(message);
messageWriter.Flush();
}
catch (Exception eScriere)
{
System.Windows.Forms.MessageBox.Show("EROARE : serverul nu a putut trimite mesaj\nEXCEPTIE : " + eScriere.Message);
return;
}
}
PS : some of the text is in romanian but it's nothing important
|
|
|
|
|
rareseu wrote: try
{
NetworkStream networkStream = new NetworkStream(socketForClients);
System.IO.StreamWriter messageWriter = new System.IO.StreamWriter(networkStream);
System.IO.StreamReader messageReader = new System.IO.StreamReader(networkStream);
}
catch (Exception eNetworkStream)
{
System.Windows.Forms.MessageBox.Show("EROARE : eroare la network stream\nEXCEPTIE : "+eNetworkStream.Message);
}// try/catch
This is where your problem is likely to be.
By declaring and instantiating the objects inside a code block (the try/catch block in this case) they are not visible to code outside of the block.
You have already declared the streams outside the block, so you are declaring new ones inside the block.
Just remove the bits, from inside the try block, struck out below and all should be well:
System.IO.StreamWriter messageWriter =
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
|
|
|
|
|
Ah can't believe i missed that , thanks Henry ! i've got new problem now but i'l start a new thread if i can't figure it out
|
|
|
|
|
I want to add some Label and Button controls on a winForm with the code(not by dragging the label and button from toolbox) in the design environment(because there are many labels and buttons need to be created ),I created a component which has a right-click menu under the design environment,when selecting one item of the menu it shows a window, and there is one button in the shown window,Now I want to add the label and button into winform that the component is located after clicling this button.
Could you give some codes to domenstrate to create one button on the form by this way?
Thanks in advance!
|
|
|
|
|
Have a look in your form's designer.cs file and see how the IDE does it and replicate that in your code.
Something like:
Button button = new Button();
button.Text = "&New Button";
button.Location = new Point(12, 12);
this.Controls.Add(button);
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
Dave,thank for your help.
I know if I write the code as you suggested and euecute it under the running time, It can create one button, but in the design time, If I execute the same code by running the button in the popup winform, it can not create button in the design winform. Could you give some advice? Thanks!
|
|
|
|
|
In order to do what you want, you will have to write your own version of the Windows Forms Designer. A lot of work.
Are you aware that if you hold down the Control key whilst selecting a component from the toolbox, you can then add multiple instances to your design surface by clicking in several places? To end this behaviour press the Escape key.
So, Ctrl-Click on Button control in Toolbox, move mouse over Form/Panel/whatever and click wherever you want a button. Added all the buttons? Press Escape or click on the next component you want from the Toolbox.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
|
|
|
|
|
Thank,Thank for your assist!
It seems to refer the EnvDTE80.DTE2 of VS2005, Because if we can create the label and button on the winform using code dynamically create them, it will save more time in our design phase.
But I try to find the way how to realize it.
|
|
|
|
|
If you want to add the button and a click event handler, you can do something like this:
namespace Test
{
public partial class MosForm : Form
{
public MosForm()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
Button Mybutton = new Button();
Mybutton.Text = "My Button";
Mybutton.Location = new Point(12, 12);
this.Controls.Add(Mybutton);
Mybutton.Click += new EventHandler(Mybutton_Click);
}
private void Mybutton_Click(object sender, EventArgs e)
{
textBox1.Text = "All done";
}
}
}
|
|
|
|
|
|
Yes I can. Can you?
Panic, Chaos, Destruction.
My work here is done.
|
|
|
|
|
No.
saoda wrote: cheeks
What's that?
जय हिंद
|
|
|
|
|
It seems like an easy problem, I think you can solve it yourself with a little bit thinking.
Hint: You can use "for" or "foreach" to check every int in the array.
|
|
|
|
|
I have a Class with a from and a basic UI (Form1), from that UI I instantiate a class (in another thread) that initializes the serial port and listens for an event that is raised when data reaches the serial port (WorkerClass). in the method launched in the class I wait 10 seconds and then the thread exits.
I launch my form and send data to my serial port, as expected nothing happens
I launch the workerthread and immediately send data to my serial port, as expected the event is raised.
After 10 seconds my worker thread exits, I send more data to the serial port, then to my surprise the event is launched ?!?
Is this normal behaviour ?
Will it last or will the garbage collector clean it from memory ?
Code the worker class:
class WorkerClass
{
public delegate void addToRTBDelegate(String text);
public event addToRTBDelegate eventRTBadd;
private SerialPort comport = new SerialPort();
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Console.WriteLine("Data received on serial port");
}
public void openCOMPort()
{
comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
comport.Open();
Console.WriteLine("Comport is Open");
for (int i = 1; i < 10; i++)
{
Thread.Sleep(1000);
}
Console.WriteLine("exited loop");
}
}
Here is my Output:
Test-Form-Thread-2.vshost.exe' (Managed): Loaded 'D:\ISS\C-SHarp\Test-From-Worker-1\Test-Form-Thread-2\bin\Debug\Test-Form-Thread-2.exe', Symbols loaded.
Comport is Open
Data received on serial port
The thread 0x27cc has exited with code 0 (0x0).
exited loop
Data received on serial port
Data received on serial port
What is happening is:
1. Start the main thread
2. Start the worker and get in a loop in the worker with a sleep
in the mean time the handler for the event is active and when data reaches the serial port, the handler sends a console message. (This is expected)
3. The worker thread exits
Now the strange part, the even handler is still active and will fire when data is received on the SP after the worker thread has terminated.
Seeing the threads runnning at various points (see below) I suspect the event handler creates a new thread that is not closed when the worker exits.
Threads before I start the worker
~ 15648 [Thread Ended]
0 4736 Worker Thread <No Name> Highest 0
0 13456 Worker Thread <No Name> Normal 0
0 13632 Worker Thread <No Name> Normal 0
0 15912 Worker Thread <No Name> Normal 0
0 11144 Worker Thread vshost.RunParkingWindow Normal 0
0 14892 Worker Thread .NET SystemEvents Normal 0
0 > 10840 Main Thread Main Thread Test_Form_Thread_2.Program.Main Normal 0
While the worker is running
~ 15648 [Thread Ended]
0 4736 Worker Thread <No Name> Highest 0
0 13456 Worker Thread <No Name> Normal 0
0 13632 Worker Thread <No Name> Normal 0
0 15912 Worker Thread <No Name> Normal 0
0 11144 Worker Thread vshost.RunParkingWindow Normal 0
0 14892 Worker Thread .NET SystemEvents Normal 0
0 > 10840 Main Thread Main Thread Test_Form_Thread_2.Program.Main Normal 0
0 15240 Worker Thread ThreadClass1 Test_Form_Thread_2.WorkerClass.openCOMPort Normal 0
0 3208 Worker Thread <No Name> Normal 0
0 12668 Worker Thread <No Name> Normal 0
After the worker exited
( the event is still activated when data reaches the serial port)
~ 15648 [Thread Ended]
0 4736 Worker Thread <No Name> Highest 0
0 13456 Worker Thread <No Name> Normal 0
0 13632 Worker Thread <No Name> Normal 0
0 15912 Worker Thread <No Name> Normal 0
0 11144 Worker Thread vshost.RunParkingWindow Normal 0
0 14892 Worker Thread .NET SystemEvents Normal 0
0 > 10840 Main Thread Main Thread Test_Form_Thread_2.Program.Main Normal 0
0 3208 Worker Thread <No Name> Normal 0
0 12668 Worker Thread <No Name> Normal 0
It is interesting to see that the worker thread is gone but threads 3208 and 12668 still exist
Is this normal behaviour ?
Thanks in advance
|
|
|
|
|
You don't need to start your own thread - SerialPort manages this for you.
The SerialPort.DataReceived event is always raised on a separate ( thread pool ) thread. Check Thread.Current.ManagedThreadId in your port_DataReceived handler.
As long as comport is alive, this event will be raised when data is received.
Nick
----------------------------------
Be excellent to each other
|
|
|
|
|
Thanks for the answer Nick, I am still a bit lost here.
Ok, serial port will raise an event as long as the port was open but how can port_DataReceived display in on COnsole.writeline if the thread for port_DataReceived is ended ?
|
|
|
|
|
Your thread running openCOMPort is not doing anything. It attaches the event handler and opens the port, but this can run on your UI thread as it doesn't take any time. Then your thread sleeps for 10 seconds before ending. It can't do anything useful when its sleeping, so it's totally pointless.
When data arrives at the port, the SerialPort instance gets a thread pool thread and raises the event on that, so port_DataReceived actually runs on a thread pool thread - see my previous reply.
You're not going to get this done today. I suggest you read http://www.albahari.com/threading/[^] over the weekend.
Nick
----------------------------------
Be excellent to each other
|
|
|
|
|
Nick, thanks for your answer I am very glad you took interest in that issue, it seems nobody is interestd in what I thought would be an interesting problem.
I have re-read the excellent tutorial from Joseph Albahari, even that there are no references on how events are handeled in threads it is still useful
The code I have posted is obviously not an application, it is just a part of a test application that will allow me to create the code for the larger one, to narrow the problem I have stripped all the un-necessary parts before posting here.
If we confine the problem to the Test application the goal is to implement an obscure serial protocol (ASTM) and to test with the other party that can be client or server.
Data can be sent to the serial port from the UI thread or from another thread in the Test app, it can also be received at any time and forwarded to the UI and/or to another thread, at that time the UI may or may not be running hence the reason to separate the serialport thread to handle the serialcomms. Also if I run all my code in the UI thread the UI freezes until I get answers from the other party, the protocol specifies extended retries and delays, another reason to have an other thread for the serial comms.
If you have time and kindness to discuss the suitability of the architecture to the task I would be delighted to provide more info for you to appreciate.
Now back to the problem.
From what you said I gather that upon binding the event a thread will be created and it will be sleeping until an event is fired.
The part I am unsure is the life of the instance and the source thread, lets say I instantiate a class CLassA with 10 methods MethodA-MethodJ from the UI thread, then in the constructor I attach the received_data event to a method, say MethodA.
When the event received_data is fired it will launch MethodA, MethodA could launch MethodB, MethodC, and an event in MethodC will send data via another event and delegate to the UI.
- Event that the event handler for Recived_data was created from the UI thread it is in it's own thread now so I assume MethodA-C will run in a different thread than the UI, is it correct ?
- What is the life of the instance of ClassA if not used for a long time ? will the garbage collector delete it ? does the garbage collector only deletes threads and not instances ?
Thanks
|
|
|
|
|
Otex wrote: Data can be sent to the serial port from the UI thread or from another thread in the Test app
I hope you're synchronizing these writes!
Otex wrote: From what you said I gather that upon binding the event a thread will be created and it will be sleeping until an event is fired
Yes! When you instantiate a SerialPort object, it starts a thread that waits for some event on the specified serial port. This is why you don't have to do this yourself - the Framework does it for you.
When some data arrives at the port, the SerialPort internal listening thread reads some data and puts it in a buffer. It then takes one of the Thread Pool threads and raises the DataReceived on that thread.
Otex wrote: The part I am unsure is the life of the instance and the source thread
Otex wrote: What is the life of the instance of ClassA if not used for a long time ? will the garbage collector delete it ? does the garbage collector only deletes threads and not instances ?
The GC deals with memory, so it operates on instantiated objects. This includes objects that control threads.
So you need to keep your SerialPort instance alive - by keeping a reference to it somewhere - and likewise you need to keep alive the object whose method is attached to the DataReceived event.
You should write a class that has a SerialPort instance member and a DataReceived handler. You should create an instance of this class in your UI thread and also keep a reference to it.
Otex wrote: Event that the event handler for Recived_data was created from the UI thread it is in it's own thread now so I assume MethodA-C will run in a different thread than the UI, is it correct ?
Yes! The main responsibility of your new class is to listen for DataReceived events, join them together to form commands in your protocol and then marshal a complete command onto the UI thread to be processed. Use Control.BeginInvoke to get back to the UI thread.
If you are still having problems, you can start a new post here with your code so far.
Nick
----------------------------------
Be excellent to each other
|
|
|
|
|
Can anyone help me with this please...
I have a c# form (form1) with a BindingSource and TableAdapter (which was added when I dropped a stored proc on the form). I need to pass this data to another form (form2) which has a datagrid. I need that data inserted into form2's datagrid so I can do some modifications to it. Once done, I then need to return all the data back to form1s BindingSource and TableAdapter. I don't think I can just pass the bindingsource because, if there was no data in in when it is passed, I need to fire a retrieve (fill) in form 2 to initially populate the data before I can modify it then return it.
Can anyone point me along the right way here?
Many thanks
modified on Friday, May 1, 2009 5:08 AM
|
|
|
|
|
Sounds like a disaster. Why not just have form2 query the same datasource ?
Christian Graus
Driven to the arms of OSX by Vista.
"I am new to programming world. I have been learning c# for about past four weeks. I am quite acquainted with the fundamentals of c#. Now I have to work on a project which converts given flat files to XML using the XML serialization method" - SK64 ( but the forums have stuff like this posted every day )
|
|
|
|
|
Hi,
I am trying to load the properties settings.settings contents in a datagrid so it can be modified and the saved to the settings.settings file.
I would like to do something elegant and extensible so when I add new settings I dont have to change all the form code.
So basically I do not want to use something like xxx= Settings.Default.Param1.ToString() but rather do a loop and put it all in an array and put it in the datagrid.
After several hours of googling and a post somewhere else I still can't find a way to do that loop, I can get the number of items in settings.settings using Settings.Default.Properties.Count but not address them in a loop using foreach or something like Settings.Default.[i].
Something that would allow me do do it is to be able to read the name of the setting/parameter in the table, again can't work out how.
Any help or pointers welcome.
Ps: I'd like to keep it simple using C# methods and functions rather than reading the file and doing de-serialisation.
|
|
|
|
|
You may be able to access more details about each setting to build a generic UI by iterating over each property - something like:
foreach (System.Configuration.SettingsProperty property in Properties.Settings.Default.Properties)
{
}
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
Excellent, that is EXACTLY what I needed.
In case someone else reads what is needed then to get the Name and value are
Console.WriteLine(property.DefaultValue);
Console.WriteLine(property.Name);
Thanks
|
|
|
|
|
I've created a c# application based on SQL Express database.
I have one view in the database based on several tables (Inner join).
When I start my appllication, I fill one DataSet with all the tables (using XSD adapters), and I fill the DataView with the view (directly from the the database).
The client user can update fields on any DataTable from the DataSet (without updating the database itself).
After the user updates the fields, I want to update the DataView with the new values, but the view is connected directly to the DataBase, and not to the DataTables.
Can I based my DataView on several DataTables, so when the DataTables are updated, the DataView is updated accordingly?
Thanks,
Maoz
|
|
|
|