|
1.
yes, I guess so. I haven't used it yet, I expect it is a regular queue plus a lock, which would be fine. If the app is adding one item (sensor value + time value) to the queue every few seconds, then obviously anything goes.
2.
don't get me started on thread priorities. IMO they aren't worth much in Windows (I have a background in embedded real-time systems). If your producer needs to have higher priotity, then the consumer might get flooded with data, and if that is acceptable, you basically are admitting you could store everything in memory before flushing it to disk...
|
|
|
|
|
Re: #2
Sure it could be flooded, but this allows for the near-time graph display (mentioned in original post, unless I am misunderstanding it); besides, storing it all in memory seemed acceptable when you proposed it earlier. I don't disagree, this may just be a way to have your cake and eat it too, so to speak.
|
|
|
|
|
if the graph is to show all the measurements (as opposed to say the last 300 samples), then all data is in memory anyway; and I'll eat the cake anyway.
|
|
|
|
|
Actually the graph show the last 60 seconds worth of data. It's about 400 odd points - I actually store 450 in a circular array so it over writes itself. I change the max and min of the time axis as each data point is added so nobody sees the missing past data. I'm surprised it works as well as it does, it gives it a cool chart recorder vibe! Maybe I should try and write an article about it.
|
|
|
|
|
I did exactly that once to experiment and check a flicker free chart would result; it looked great indeed, whereas lots of people seem to believe it can't be done in WinForms at all.
|
|
|
|
|
Mine WPF using the WPF toolkit from CodePlex.
|
|
|
|
|
Thanks for the suggestion. I'll look into it.
|
|
|
|
|
I had to do something very similar at a previous job. I set it up so that each data source (your sensor) had it's own reader thread. This thread parsed out the data and made note of other things like timing, etc. Each reader had a collection of data sinks, which was just a generic term for a consumer of the data. The reader would pass on each chunk of data to each data sink, which in turn would do whatever it wanted with the data. If you try something similar, you could have both your real-time graph and the file be data sinks. The real-time graph data sink could have it's own thread and 60-second circular queue. The file data sink could use its own queue or write the data directly to the file. Personally, I'd have the data file use another thread and queue and write data to the file in chunks of say 5-10 seconds or so. It's fast enough that you shouldn't lose too many data points if something goes wrong, and it's infrequent enough that things should not get bogged down.
|
|
|
|
|
Interesting. I like your set up with the idea of data sinks. One other problem that I didn't really elaborate on in my original post is that I need to trigger other things based on the data coming in, so, for example, when the data crossing a threshold I need another device to be triggered. So I really need to have at least one sink be "high-priority" because it has to identify certain conditions in the data and react as quickly as possible.
|
|
|
|
|
Wjousts wrote: The data coming from the sensor isn't particularly fast, it's about 7Hz and what I need to store is the time since the start of recording (in seconds, stored as a double) and the value from the sensor (also a double). I could easily see an hour of data being collected at one time which I (very) roughly estimate as being about 1.5 Mb of raw data. Ultimately this would need to be saved in a human readable format (or at least an Excel importable format) maybe tab delimited text, so the file size on disk would be several times bigger.
So any thoughts? Recommendations? Am I better off trying to store as much as possible in memory and then only write to disk when recording ends? Or is it better to try and write pieces as it's collected?
Where 7 Hz = 7 inputs per second?
In a 24 hour period that gives you 600,000+ rows. Exclusive of finding one value at a specific time or a range in small interval that isn't going to be human readable regardless of what you do.
Storage as text if you store only the time would be probably 12 meg for each day.
You could do one csv file per day.
If you really want to do time since start rather than time of day then you should plan on putting the time the app started either in the file name or at the beginning of the file. The date of course would be in the file name.
|
|
|
|
|
Okay, human readable is the wrong phrase, importable into Excel or something similar is what I meant. We wouldn't collect 24 hours worth of data at a time anyway. Probably not more than about 1 hour tops, and what we need to be able to do is graph that data and see how well it matches up with data coming from somewhere else.
Putting the time in the filename is a nice idea though. It eliminates the mess of letting users decide what the file should be called as well.
|
|
|
|
|
I also recommend looking at the performance of your program too. I think you're not storing huge amounts of continuous data. I use a profiler http://www.red-gate.com/products/dotnet-development/[^] to help me spot nastiness. When collecting data from devices, it pays to make sure that your program runs smoothly and doesn't accumulate extra memory.
I know it's a little off topic, but doing performance analysis has helped me quite a bit.
"Simplicity carried to the extreme becomes elegance."
-Jon Franklin
|
|
|
|
|
hi guys, i have a form that needs to call a function on his opener form. How can i do this?
ex: form1 opens form2, and form2 needs to call a method in form1.
thanks a lot!
|
|
|
|
|
Make the method public, and pass a reference to itself to the second form (in the second form's constructor).
*** In Form1 ***
Form2 form2 = new Form2(this);
*** In Form2 ***
public Form2 (Form1 form1) : this()
{
_form1 = form1;
}
private Form1 _form1;
|
|
|
|
|
i've used From2 f = new Form2(ref Form1 this); but didnt work.
|
|
|
|
|
This works for me. Two forms, one with a button and textbox (Form1), the other just a button (Form2).
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2(this);
form2.Show();
}
public void Change(string text)
{
textBox1.Text = text;
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public Form2(Form1 form1) : this()
{
_form1 = form1;
}
private Form1 _form1;
private void button1_Click(object sender, EventArgs e)
{
_form1.Change("Put some text in the TextBox");
}
}
|
|
|
|
|
ok, almost there... i got only one more problem... i need to pass 2 param to my form2.
ex: From2 form = new Form2(id, this);
|
|
|
|
|
Just change the constructor... Simple.
public Form2(int id, Form1 form1) : this()
{
_id = id;
_form1 = form1;
}
private int _id;
private Form1 _form1;
|
|
|
|
|
solved... just removed the : this().
anyway... thank you very much
|
|
|
|
|
The this() call makes the constuctor call the lower-level constructor overload. In this example, Form2(Form1 form1) : this() causes it to call public Form2() during its execution, which thereby causes it to call InitializeComponent(); (and anything else inside Form2() ).
If you don't have a parameter-less constructor overload of course, it will fail.
public Form2()
{
InitializeComponent();
}
public Form2(Form1 form1) : this()
{
_form1 = form1;
}
|
|
|
|
|
you can do it something like:
using(Form2 frm2 = new Form2())<br />
{<br />
frm2.myVoid();<br />
}
I Love T-SQL
"Don't torture yourself,let the life to do it for you."
If my post helps you kindly save my time by voting my post.
www.aktualiteti.com
|
|
|
|
|
your answer is not clear at all.
If this is a third form you are creating, it is wrong as it would not share anything with the original Form it is trying to interact with.
|
|
|
|
|
Either do the way others have suggested or follow on of the following approach:
1. Create a class called Common or something similar and place the methods used by more than one forms there. Then all the forms can call methods in this class. Or
2. Have a base class that contains common methods (possibly marked virtual) and all forms in your application inherit from that class.
|
|
|
|
|
I never like solutions that include a child knowing about its parent. I question whether the UI forms should be communicating directly in the first place and if some re-architecturing needs to take place on that design.
But suffice to say, if the forms do need to communicate, I would much rather see it done where Form2 raises an event for which Form1 creates a handler when creating Form2. That way, at least the child still knows nothing about the parent.
if( eventToCall != null )
eventToCall();
I wasn't, now I am, then I won't be anymore.
|
|
|
|
|
With events instead, it could look something like this. (Probably better to pass the message in an event argument, though.)
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
form2.Clicked += new EventHandler(form2_Clicked);
}
private void form2_Clicked(object sender, EventArgs e)
{
textBox1.Text = form2.Message;
}
private void button1_Click(object sender, EventArgs e)
{
form2.Show();
}
private Form2 form2 = new Form2();
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Message = "Here is some text";
if (Clicked != null) Clicked(sender, e);
}
public string Message = string.Empty;
public event EventHandler Clicked;
}
[Edit] Public to private on Form2.
modified on Wednesday, January 5, 2011 1:31 PM
|
|
|
|