|
I'm not doubting you, just doubting the sanity of the behaviour.
I guess it allows you to add controls for showing later, without them ever flashing onto the screen, although setting visible to false before adding them to the controls collection would achieve that also.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Hey!
I am using System.IO.SerialPort in framework 2.0(Beta2) to listening on the port. I am also using DataReceived event on the serialPort object.
I have set the threshold to 1, this means that the event(DataReceived) will fired as soon as 1 byte is written to the serialport.
When this event is triggerd, I am using a ThreadPool to queue work to my OnRecivedData() method.
In OnRecivedData() I first reads existing on the serialport, but I also writes this icoming data to file.
To see if this realy got what it takes I have made som test. I am sending data as fast as posible over the nullmodem cable with the follwing port settings:
Baud: 11 5200
Data: 8
Parity: None
Stop; 1
Problem:
I have compared the file that I send, and the file I recived(creates) and this works fine in low speeds, but whenI am pushing the system to 100% load my program by moving around a window or something, It loses data?
I realy have to get a stable connection even during stress.
I first thought that I could set the ThreadPool to a higher priority, but I havent found any way to do this? It could also be the evnet(DataReceived) that is never fired, can I set higher priority on this event?
Best Regards
SnowJim
|
|
|
|
|
Your code for recieving data should itself be in a worker thread, so that it continues to function even when the UI thread is maxed out by you moving a window.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Yes, as I said, I use ThreadPool as soon as the event is triggerd.
Or do you mean that i need a separate thread for the event? I thought that when an event accure, then a new thread is automatly created to handle this event? or is it the main(GUI) thread that will be used to the event? And if so, is there any way to get an own thread to this?
BestRegards
SnowJim
|
|
|
|
|
It really shouldn't be losing data, under any circumstances. Did you view the file after closing the application? Maybe it was just getting buffered in memory?
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
Yes i know that there may be a buffert. But this buffert is flushed and writen to the file.
If i dont move the Window around so i get 100% CPU usage, the transfere works fine.
It is not losing data in the end, its on diffrent places al the time, and its often some lines of data(maby 5-6 that disipares?
But the Thread that runns the event? is this Thread, the same as the main thread(the thread that draws the GUI)?
Best Regards
SnowJim
|
|
|
|
|
Hmm. How are you running OnReceived? Are you using ThreadPool.QueueWorkItem or the BeginInvoke method on a delegate object? If so, your function is running on a separate thread, not the UI thread. However, if you are calling BeginInvoke on an object derived from Control (like Form, TreeView etc..) then the function will run on the main thread (UI thread).
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
Yes i am using the SerialPort.DataReceived Event.
I have done some more testing now!
In the DataReceived event funktioner(the funktion that the DataReceived envet will run) u placed the code that writes the data to the file, like this:
<br />
lock (this)<br />
{<br />
if (RUNNING)<br />
{<br />
RemovePortHandlerRAW.Write(serialPort.ReadExisting());<br />
RemovePortHandlerRAW.Flush();<br />
<br />
}<br />
}<br />
RUNNING will be true as long as i dont close the port.
I have tryed to changes the serialPort.ReceivedBytesThreshold to all between 1 and 512, but there is not much diffrenc.
If i dont move around some windows and dont get 100% CPU usage, the tranfere file is a perfect match to the one i sent. But if i move around the window so i get 100% CPU usage, then i will lose data in diffrent places?
It simes like that the event will not be fired as is would!?
I have thought of going back to a Thread that goes in a loop and check if there is somthing to read, and if, then it will read it, but this take some performance even if there is no data to be read.
Any sugestions?
BestRegards
SnowJim
PS hope you understand my english
|
|
|
|
|
Hey!
I have now runned some more tests!
I have made a Thread with priotity = normal, that runns in a loop as long as RUNNING == true, if serialPort.BytesToRead > 0, then it will read from the port and write it to file. If not, it will Thread.sleep(1).
This method is not working bether then the event method I dont realy know how to solve this problem, I must ensure that no data is lost in the transfare, no mather what.
Maby all programs will made mistakes when CPU usage is on 100%(when moving around(fast) for example a browser with alot of content)?
My program have not realy a GUI, its a "window control library"(homemade control), i am adding this dll(Window control library) to an other project with a form, with two buttsons(open/close). This means that there is no real time display of the incoming data(now adance GUI to redraw).
I am sending 100 000 rows that contains up to around 64 chars, when CPU usange is on 100% it misses rows, often up to 20-30 rows i have seen.
If you got any ide how to proccead, let me know!
Best Regards
SnowJim
|
|
|
|
|
Have you tried to create the System.IO.SerialPort in a thread of its own yet?
like this:
<code>
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;
using System.IO.Ports;
namespace SerialTest
{
class SerialReceiver
{
private System.Threading.ManualResetEvent m_Closed = new System.Threading.ManualResetEvent(false);
private System.IO.Ports.SerialPort m_Port = null;
private Thread m_Thread = null;
public SerialReceiver()
{
this.m_Closed = new ManualResetEvent(false);
this.m_thread = new Thread(new ThreadStart(this.ThreadEntry));
this.m_thread.Start();
}
public ~SerialReceiver()
{
Close();
}
public void Close()
{
this.m_Closed.Set();
}
public void ThreadEntry()
{
this.m_Port = new System.IO.Ports.SerialPort("COM1");
this.m_Port.ReceivedBytesThreshold=1;
SerialDataReceivedEventHandler receivedHandler = new SerialDataReceivedEventHandler(Port_DataReceived);
this.m_Port.DataReceived += receivedHandler;
this.m_Port.Open();
this.m_Closed.WaitOne();
this.m_Port.OnDataReceived+= receivedHandler;
}
void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] data = new byte[this.m_Port.BytesToRead];
this.m_Port.Read(data,this.m_Port.BytesToRead);
foreach(byte b in data)
{
}
}
}
}</code>
The code is not testet and a prototype (i do not have the 2.0 framework installed yet)
Btw. do you check if more than one byte is avail in your event handler? Even though the threshold for the event is 1 it is quite possible that there has more than one byte arived when the event is finally triggert.
/cadi
|
|
|
|
|
Thanks for your time!
You solution did unfortunately not solve this problem =(
I have thougt of that it maby is the serialPort that cant handle the stress. But i have tryed another serialPort program, and this program generates the exact same file, not data loses!
This most with other words have to do with my software, then if it is the MS serialport that cant handle the stress or if its me that makes any thing wrong is hard to tell.
Is there anyone else that could test this and comfirme the same problem?
Best Regards
SnowJim
|
|
|
|
|
Some more testing is done!
I am no following Cadi´s exampel to let e separate Thread create the serialport, just to be sure that the event is not using the main Thread, but this special serilport creater thread, is this right?
Testing:
If i open a directore in Windows that contains some files and press and hold F5(update) so i get 100% CPU usage while my program is recieving data in high speed there are no data loses? But if i move around the Firefox(web browser) with a advance page open and get 100 % CPU usage that way, then i lose data? how is this posible?
I have notce that i somtimes get that the Thread is interupted, this must have somthing with the GUI/Main Thread to do, right? it is oly coming when moving around the window?
Maby this is a problem that i shold not count on? i know that the for example Winamp works fine with this stress test(moving around the window) with out stop playing music, but maby its a diffrent thing with the serialport?
Any sugestions is welcome
Best Regards
SnowJim
|
|
|
|
|
I'm writing an app for XP that will need to have a custom shutdown procedure. I'd like to initiate this procedure with the press of the physical power button on the computer. Is there any way to catch this event?
Thanks!
Dmitriy
|
|
|
|
|
|
The problem is that my shutdown procedure will take too much time and Windows will terminate it prematurely.
I need Windows to ignore the event (configure it to "Do Nothing" in the power management config), but for my application to handle it.
Thanks
|
|
|
|
|
I thought the shutdown event sends a shutdown message to all applications, and then waits for them to end ? Although, I guess if it will take too long, it will bring up a 'terminate this application', I'm pretty sure if you have an edited Word document for example, and you press shutdown and then hit 'cancel' on the 'do you want to save changes' dialog, it won't shut down. Therefore, you should have control to stop it, and then send your own shutdown event. If it's going to take that long, you should let the user know what's going on, or they'll think their PC is broken, and pull the plug out anyhow.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Hmm... I think you're right about the MS Word behavior. So you think there's an event that an application can generate that makes Windows cancel the shutdown? Any idea where I can read up on this?
|
|
|
|
|
According to the MSDN link I gave you above, the SessionEndEventArgs object passed in has a 'cancel' property. If you set it to true, you cancel the request for shutdown.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Sorry, somehow I spaced out and didn't see the link. That's exactly what I wanted to know, thanks!!!
-Dmitriy
|
|
|
|
|
I have used Spy++ to obtain the handle of a Window Panel and TreeView. I now want to use this handle to grab the tree. I don't understand how to do this ?? Any suggestions.
Once I grab the tree I want to be able to store this tree in a file.
Could someone please give me some direction here
Abhishek Karnik
|
|
|
|
|
You can't create a .NET TreeView instance from a handle to a window.
One way would be to send windows messages to this window handle to get information about the tree. Search MSDN for treeview messages, they usually start with TVM_...
But nevertheless, I think your question doesn't belong to the C# forum. Try the Visual C++ forum instead.
Regards,
mav
|
|
|
|
|
Hey,
Thanx ..lemme give it a shot there.
Regards,
Abhishek
|
|
|
|
|
Hy, I Got a programming question on .NET remoting in C#:
Following scenario:
I've a server application and client applications with the graphical front end.
the server app marshales an object(a class for all the settings the client apps
need to know) via:
----------------------------------- server code snippet----------------------------------
BinaryServerFormatterSinkProvider serverProv = new BinaryServerFormatterSinkProvider();
serverProv.TypeFilterLevel = TypeFilterLevel.Full;
BinaryClientFormatterSinkProvider clientProv = new BinaryClientFormatterSinkProvider();
IDictionary props = new Hashtable();
props["port"] = 9999;
m_TcpChan = new TcpChannel(props, clientProv, serverProv);
ChannelServices.RegisterChannel(m_TcpChan);
sO = new ServerObject(mainClass.loadSets(), (IServer)this, mainClass.loadLogs());
sO.Clients = new ArrayList();
obj = RemotingServices.Marshal(sO, "settings");
----------------------------------------------------------------------------------------
and the client apps are "connecting" via:
------------------------------------client code snippet---------------------------------
TCP = new TcpChannel(0);
ChannelServices.RegisterChannel(TCP);
sO = (Interface.ServerObject) Activator.GetObject(typeof (Interface.ServerObject), "tcp://" + remoteIP + ":9999/settings");
----------------------------------------------------------------------------------------
know I can access sO.settings... to retrieve data I need on the client's side.
but there're also "remote methods" I cann call via:
sO.IServer.myServerRemoteMethod();
and: sO.ICLient.myClientremoteMethod(); (on the server side)
up to this point everything is working correctly!
my problem is that after somte time I can't call the remote methods anymore, the error is: "
System.Runtime.Remoting.RemotingException: Requested Service not found....
so I looked around some time to solve my problem and I read something about "Object Lifetime" and
"Leased Based Manager", I think my "remote methods" are destroyed after that standart 5min. of lifetime,
is that correct?! do I just have to return "null" in the overriden InitializeLifetimeService()
method? how to? that way?
public override Object InitializeLifetimeService()
{
ILease lease = (ILease)base.InitializeLifetimeService();
if (lease.CurrentState == LeaseState.Initial)
{
lease.InitialLeaseTime = TimeSpan.FromMinutes(1);
lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);
lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
}
return null;
}
I'm totally confused...
btw: I don't even know, if I have client activated or server sided object,
or whether I'm using singleTon or singleCall...
What would be the best solution for this Programm?
I'm looking foward for any help!
OpaKnack
|
|
|
|
|
Hi!
You're using an object that's marshalled explicitely, so it's similar to a singleton, but not exactly the same (a singleton doesn't exist before the first client requests one, for example).
For your ServerObject not to die you do have to override InitializeLifetimeService() , but you can skip all that ILease stuff and just return null.
Another important point is to watch the scope of your ServerObject sO .
If you declare it within your startup routine, it'll fall out of scope when startup is finished and will get garbage collected.
So it should be a member of a class you keep alive as long as your server application is running.
Regards,
mav
|
|
|
|
|
Thank you for you're quick response!
I think I've to override InitializeLifetimeService() on my server App, don't I?
I already declared "ServerObject sO" in my Class, so I can use it outside the startup routine.
But if my serverObject dies after 5min.(so that I can't use the remote methods anymore) why can I still access the "settings" instance in the ServerObject(sO.settings)?
That means:
I can use: sO.settings.userName (it's a string)
but I can't use: sO.IServer.myRemoteMethod()
OpaKnack
|
|
|
|