Может быть, мой код является дубликатом, но на самом деле я попробовал другие решения и не смог решить проблему.Форма графика не является моей основной формой, но она открывается из основной формы.в основной программе у меня есть [STAThread] перед Main ().Я хочу запустить Ploting () для обновления графика, если произойдут какие-либо изменения в данных в таблице sql.мой код выглядит следующим образом:
namespace MainProject1{
public partial class Plot : Form
{
System.Timers.Timer timer = new System.Timers.Timer();
BackgroundWorker PlotWorker;
public Plot()
{
InitializeComponent();
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
PlotWorker = new BackgroundWorker();
PlotWorker.DoWork += new DoWorkEventHandler(PlotWorker_DoWork);
PlotWorker.WorkerSupportsCancellation = true;
//Ploting(); //here it works
}
void PlotWorker_DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
//Ploting(); //here also receive the error.
if (PlotWorker.CancellationPending)
{
e.Cancel = true;
return;
}
}
}
private void timer_Elapsed(object sender, ElapsedEventArgs elapsedEventArg)
{
Ploting(); //here i receive the error
}
private void test_Click(object sender, EventArgs e)
{
timer.AutoReset = true;
timer.Interval = 100;
timer.Start();
}
private void Ploting()
{
try
{
var list1 = new List<double>();
var list2 = new List<double>();
SqlResultTable rt = new SqlResultTable();
rt.ReadtoPlot(84, "readingS", ref list1, ref list2); //here i read the data from sql. it works corrrect.
cartesianChart1.Series = new SeriesCollection
{
new ScatterSeries
{
Title = "Setpoints",
Values = new ChartValues<double>(list1),
PointGeometry = DefaultGeometries.Diamond,
StrokeThickness = 2,
Fill = Brushes.Transparent,
},
new LineSeries
{
Title = "UUT readings",
Values = new ChartValues<double>(list2),
LineSmoothness = 0,
PointGeometrySize = 10
},
};
cartesianChart1.DataClick += CartesianChart1OnDataClick;
}
catch(Exception err)
{
MessageBox.Show(err.Message);
}
}
private void CartesianChart1OnDataClick(object sender, ChartPoint chartPoint)
{
MessageBox.Show("You clicked (" + chartPoint.X + "," + chartPoint.Y + ")");
}
}
}
, когда я использую метод Ploting () в конструкторе, он работает, но когда я использую его в работнике или в timer_Elapsed, я получаюошибка снова.Я знаю, что это как-то связано с потоком, но не знаю, как это решить.Я попытался создать новый поток в фоновом режиме или timer_Elapsed, но получил еще одну ошибку.Извините за вопрос.Я новичок в C #!
Новое обновление: код с делегированием:
namespace MainProject1{
public partial class Plot : Form
{
public delegate void plotDel(); //**** new added ***
System.Timers.Timer timer = new System.Timers.Timer();
BackgroundWorker PlotWorker;
public Plot()
{
InitializeComponent();
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
PlotWorker = new BackgroundWorker();
PlotWorker.DoWork += new DoWorkEventHandler(PlotWorker_DoWork);
PlotWorker.WorkerSupportsCancellation = true;
plotDel pl1 = OnPlotNeeded; //**** new added ***
//Ploting(); //here it works
}
protected virtual void OnPlotNeeded() //**** new added ***
{
Ploting();
}
void PlotWorker_DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
//Ploting(); //here also receive the error.
if (PlotWorker.CancellationPending)
{
e.Cancel = true;
return;
}
}
}
private void timer_Elapsed(object sender, ElapsedEventArgs elapsedEventArg)
{
System.Threading.SynchronizationContext.Current.Post(new System.Threading.SendOrPostCallback(o => Ploting()), null); //when i add this line, it does not go to next line(no error, no action) and without it, again receive the error as before!
OnPlotNeeded();
}
private void test_Click(object sender, EventArgs e)
{
timer.AutoReset = true;
timer.Interval = 100;
timer.Start();
}
private void Ploting()
{
// the inside code is same as first code
}
private void CartesianChart1OnDataClick(object sender, ChartPoint chartPoint)
{
MessageBox.Show("You clicked (" + chartPoint.X + "," + chartPoint.Y + ")");
}
}
}