Witam
Piszę aplikację do monitorowania sygnału EKG.
Zacząłem od stworzenia własnej kontrolki rysującej na "żywo" wykres EKG. Żeby sygnał był rysowany na bieżąco bez żadnych opóźnień i ze stałą częstotliwością rysowanie oparłem na timerach.
Gdy używam timerow z Win Fromsow wykres rysuje się płynnie ale po załączeniu kolejnych wykresów wszystkie strasznie zwalniają. Przy 10 wykresach picturebox odświeża się tylko kilka razy na sekundę. (chciałbym osiągnąć przynajmniej 30, przy min 6 wykresach).
Podczas rysowania jednego wykresu obciążenie procesora wynosi kilka %, przy kilku wykresach dochodzi do 60%
Gdy używam timerow z klasy System.Timers które działają w osobnych wątkach wykresy nie zwalniają już tak bardzo ale i tak nie da się utrzymać stałej prędkości odświeżania. Pojawia się też inny problem. Gdy rysowany jest jeden wykres to działa on w miarę płynnie, obciążenie procesora kilka %. Po załączeniu kolejnych wszystkie zaczynają migać, im więcej uruchomionych wykresów tym gorzej( a obciążenie procesora po dodaniu zaledwie jednego % wzrasta do 50%, przy kilku wykresach do 80%.)
Tak jakby kolejne uruchomione UserControl negatywnie na siebie wpływały (a przecież są to osobne obiekty i każdy z nich ma osobne timery/wątki ??? )
Próbowałem chyba wszystkie kombinacje z uruchamianiem poszczególnych metod na różnych wątkach, używałem locków, delegatów, i innych mechanizmów. Za każdym razem picturbox
y "migają"...
Siedzę już nad tym dość długo i kończą mi się pomysły.... nie wiem czy moje podejście jest dobre ?
czy żeby utrzymać stałą prędkość wykresów należy używać timerów czy jest jakiś inny dobry mechanizm. Jak można to zoptymalizować ?
Bardzo proszę o pomoc
W kodzie umieszczone są metody obu typów timerów.
Niedorysowane fragmenty wykresów to właśnie efekt "migania"
<url>http://imageshack.us/photo/my-images/689/beztytuumev.jpg/
</url>
private void AddSample()
{
//przesuniecie wskaznika odczytu na poczatek
if (it == buforLenght)
{
it = 0;
}
//przesuniecie okna o jedna probke
for (int i = 0; i < buforLenght - 1; i++)
{
buforChart[i] = buforChart[i + 1];
}
//dodanie nowej probki
buforChart[buforChart.Length - 1] = buforSamples[it];
}
//RYSOWANIE NA PICTBOX
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(bmp, 0, 0);
}
////////////TIMERY -> WIN FORMS
private void timerBufor_Tick(object sender, EventArgs e)
{
AddSample();
it++;
DrawBmp();
}
private void timerRender_Tick(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}
////////////TIMERY -> KLASY SYSTEM.TIMERS
void systemTimerBufor_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
lock (zamek)
{
AddSample();
it++;
DrawBmp();
}
}
void systemTimerRender_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
lock (zamek)
{
pictureBox1.Invalidate();
}
}
//RYSOWANIE NA BITMAPIE
private void DrawBmp()
{
x0 = 0;
y0 = 0;
x = 0;
y = 0;
graphics.Clear(System.Drawing.Color.White);
for (int i = 0; i < buforLenght; i++)
{
y = -(float)((buforChart[i] * ampfilter) - (pictureBoxHeight / 2) + signalLocation + signalLocationHidden);
if (i == 0)
y0 = y;
x = i;
graphics.DrawLine(Pens.Red, x0, y0, x, y);
x0 = x;
y0 = y;
}
}