now I'm working on some code that will control external FPGA and draw some data on WF chart. It has complete functionality now, but I'm interested in better practices of doing interfaces.
I have UI thread that spawns control thread --> control thread in his order spawns computing thread (now it just calculates points on circle) and GUI_refresher thread that change text of label's and draw points on chart;
GUI_refresher have an option just draw one point or trace envelope; controls by bool flag
I'm interested in all that you can recommend from code arrangement and naming style to better ways of coding itself)
It hasn't any architecture, it's just prototype where I'm learning how to do interfaces. If u can help with it too, I will appreciate it.
the full solution for those who want to run it himself:
the code sample in that improvement I'm most interested:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.Threading;
using System.Timers;
namespace interfaceTest_SD1
{
class doComputingThread
{
private AutoResetEvent autoevent = new AutoResetEvent(false);
public delegate void Refresher(string text);
public readonly ConcurrentQueue<coords> _queue = new ConcurrentQueue<coords>();
public delegate void _dGuiRefresher(bool flag);
public static System.Timers.Timer _timer;
public int numOfCycle { get; set; }
public struct coords{
public int X;
public int Y;
}
private coords Coordinate;
Form1 myform;
public doComputingThread(Form1 form)
{
myform = form;
}
public void MainThread()
{
bool flag;
_timer = new System.Timers.Timer();
_timer.Interval = 10;
_timer.Elapsed += (sender, e) => { GuiRefresher(true); };
_timer.Enabled = true;
for (int i = 0; i < numOfCycle; i++)
{
Thread _ComputeThread = new Thread(new ThreadStart(ProducerThread));
_ComputeThread.Start();
flag = i == 0 ? true : false;
_timer.Enabled = true;
_ComputeThread.Join();
autoevent.WaitOne();
_timer.Stop();
_timer.Elapsed -= (sender, e) => { GuiRefresher(true); };
//_timer.Elapsed += (sender, e) => { GuiRefresher(false); };
}
}
public void ProducerThread()
{
int veyerstrasse = 0;
int statement = 100 ^ 2;
//populate queue
int X = 0;
int Y = 0;
for (double t = 0; t < 2 * 3.14; t = t + 0.1)
{
X = (int)(Math.Cos(t) * 5000);
Y = (int)(Math.Sin(t) * 5000);
Coordinate.X = X;
Coordinate.Y = Y;
_queue.Enqueue(Coordinate);
}
}
public void GuiRefresher(object flag)
{
if (_queue.TryDequeue(out Coordinate))
{
Action action = () =>
{
myform.label1.Text = Coordinate.X.ToString();
myform.label2.Text = Coordinate.Y.ToString();
};
myform.Invoke(action);
if ((bool)flag == true)
{
action = () =>
{
myform.chart1.Series["Series1"].Points.AddXY(Coordinate.X, Coordinate.Y);
};
myform.Invoke(action);
}
action = () =>
{
myform.chart1.Series["Series2"].Points.Clear();
myform.chart1.Series["Series2"].Points.AddXY(Coordinate.X, Coordinate.Y);
};
myform.Invoke(action);
Thread.Sleep(40);
}
else
{
autoevent.Set();
}
}
}
}