|
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
|
|
|
|
|
Have a Google for 'updateable views c#', then pick one of the hundreds of hits, that most nearly fits your situation.
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.”
|
|
|
|
|
I write the following storePrpcedure:
create PROCEDURE [dbo].[Ins_Products]
-- Add the parameters for the stored procedure here
@ProductName nvarchar(max),
@ProductModel nvarchar(max),
@ProductColor nvarchar(50),
@ProductDescription nvarchar(max),
@ProductPrice bigint,
@ProductQuantity int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
declare @ProductID bigint;
--set @ProductID=-1
if Not Exists ( Select @ProductID = ProductID From Products
Where ProductModel=@ProductModel)
Begin
Insert Into Products (ProductName,ProductModel,ProductColor,ProductDescription,ProductPrice,ProductQuantity)
Values(@ProductName,@ProductModel,@ProductColor,@ProductDescription,@ProductPrice,@ProductQuantity)
select @ProductID=@@Identity
End
else
Begin
Update Products
Set ProductName=@ProductName ,ProductModel=@ProductModel ,
ProductColor=@ProductColor,
ProductDescription=@ProductDescription,
ProductPrice=@ProductPrice,ProductQuantity=@ProductQuantity
where (ProductID=@ProductID)
End
return @ProductID
END
but it couse error:
Msg 102, Level 15, State 1, Procedure Ins_Products, Line 26
Incorrect syntax near '='.
Msg 156, Level 15, State 1, Procedure Ins_Products, Line 33
Incorrect syntax near the keyword 'else'.
what should I do?!!
?!!!!!
modified on Friday, May 1, 2009 4:10 AM
|
|
|
|
|
This is C# Forum. You should post the question in SQL Forum.
|
|
|
|
|
Nafiseh Salmani wrote: select @ProductID=@@Identity
Shouldn't that be:
SET @ProductID = @@Identity
My failometer is detecting vast quantities of FAIL!
"Its SQL - hardly programming..." (Caslen)
|
|
|
|
|
Hello,
I have a string Variable ( string MyDataSet = "abcdef" + "DS" ).
I would like to use this string variable to instanciate a new dataset ( DataSet MyDataset = new dataSet()).
Please how can do this?
I tried to make a void to do this with accessor (GET SET) but without result.
My best regards.
Best regards.
|
|
|
|
|
I think you need to explain what you want to do. What it looks like to me is that you want a dynamic reference for objects in your code, which is very odd...
|
|
|
|
|
Is it possible you want to name the dataset?
MyDataSet.Name = string variable.
You may even be able to do = new dataset(stringvariable)
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
This is a great windows based NMS tool. Enterprise grade network management software with a very easy to use interface that has tons of features.
Comes with a 30 day trial but you can download it here without registering it ahead of time.
http://www.dopplervue.com/software/setup.exe
Diassemble it for complete code samples of how to do this stuff.
http://www.red-gate.com/products/reflector/
Create plug-ins by adding pollers. One simple entry in a database table and a dll written in .NET.
|
|
|
|
|
You should pay the site if you want to advertise stuff.
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 )
|
|
|
|
|
I'm making a small game, but because I'm new to VS C# .NET, so I need help please look at this form:
http://picasaweb.google.com/lh/photo/49JsG9IIMP9ByRsjSrxZFg?feat=directlink
There's a table with rows, and columns. Two ( 2) button: Add Row and Add Column. How to do( how to code?): - when user click Add Row button, my program add one( 1) row, with the same height with other rows. - when user click Add Column button, add one column, with the same width. - In my program has an Array: a[r][c], r: number of row, c: number of column. Of course that r and c can not be greater than 500( or somethings like that, because I do not intend to show more than 200s rows or columns). When click on Cell at position row 10, column 4, that Cell will change color to black. And If user press a number-key, a[9][3]= that number. For example, in that pic I showed, it's 9. Should I use TableLayoutPanel, or other Control? Thanks!
|
|
|
|
|
It all depends what you want to do.
Easiest (IMHO) would be to use a datagridview.
Plonk one on teh form, and put this code in the onclick events of your two buttons...
private void button2_Click(object sender, EventArgs e)
{
dataGridView1.Rows.Add(1);
}
private void button1_Click(object sender, EventArgs e)
{
dataGridView1.Columns.Add("name", "headername");
}
and yo'll have the basics.
Note you (probably) don't need to have an array as teh grid itself is effectively an array - so just store whatever you need in there.
In the KeyPress event of your grid you can thn have
private void dataGridView1_KeyPress(object sender, KeyPressEventArgs e)
{
dataGridView1.CurrentCell.Value = e.KeyChar;
}
You'll need to filter the keypresses to handle only what you want - but that should get you started...
___________________________________________
.\\axxx
(That's an 'M')
|
|
|
|
|