Многопоточность проблема в C # - PullRequest
0 голосов
/ 14 июня 2019

Я пытаюсь отобразить данные с интервалом в моем приложении Windows Forms.

Мне нужно, чтобы графические элементы запускались в отдельном потоке, но у меня три вызываемых функции, и я не могу просто использовать поток.start ();

Я попытался запустить только элементы управления в своем собственном потоке, но он говорит мне, что другой поток владеет элементами управления.

Когда я запускаю программу как есть, диаграмма ужасно отстает, что означает, что она должна быть в независимом потоке

Все это нужно запускать в отдельном потоке, потому что моя форма отстает при обновленииэто

public void GraphData()
{
    var mapper = Mappers.Xy<MeasureModel>()
    .X(model => model.DateTime.Ticks)   //use DateTime.Ticks as X
    .Y(model => model.Value);           //use the value property as Y

    Charting.For<MeasureModel>(mapper);

    //the ChartValues property will store our values array
    ChartValues = new ChartValues<MeasureModel>();
    cartesianChart1.Series = new SeriesCollection
    {
        new LineSeries
        {
            Values = ChartValues,
            PointGeometrySize = 1,
            StrokeThickness = 2
        }
    };

    cartesianChart1.AxisX.Add(new Axis
    {
        DisableAnimations = true,
        LabelFormatter = value => new System.DateTime((long)value).ToString("hh:mm:ss"),
        Separator = new Separator
        {
            Step = TimeSpan.FromSeconds(1).Ticks
        }
    });

    var thread = new Thread(() =>
    {

        SetAxisLimits(System.DateTime.Now);

        Timer = new System.Windows.Forms.Timer
        {
            Interval = 20

        };

        Timer.Tick += TimerOnTick;
        Timer.Tick += timerdata_event;
        Timer.Start();
    });
    thread.Start();
}

public ChartValues<MeasureModel> ChartValues { get; set; }
public System.Windows.Forms.Timer Timer { get; set; }

private void SetAxisLimits(System.DateTime now)
{
    cartesianChart1.AxisX[0].MaxValue = now.Ticks + TimeSpan.FromMilliseconds(1000).Ticks; // force the axis to be 100ms ahead
    cartesianChart1.AxisX[0].MinValue = now.Ticks - TimeSpan.FromSeconds(4).Ticks; // only care about the last 8 seconds
}

private void TimerOnTick(object sender, EventArgs eventArgs)
{
    var now = DateTime.Now;
    var queue = new Queue(tempStore);
    var b = queue.Dequeue();

    ChartValues.Add(new MeasureModel
    {
        DateTime = now,
        Value = double.Parse(b.ToString())
    });

    SetAxisLimits(now);

    if (ChartValues.Count > 100) ChartValues.RemoveAt(0);
}

Ответы [ 2 ]

0 голосов
/ 14 июня 2019

есть две вещи ... 1. Окна формы используют очередь, а не многопоточность, и она построена на событии STA (Single Thread Architect), хотя, когда мы смотрим на нее, она выглядит как MTA ... Итак, во-первых, если вызапустить в отдельном потоке, вы должны синхронизироваться с очередью Windows ... это иногда даже вызывает ошибки, если вы не делаете этого, когда вы работаете с элементами управления

, вызывая: this (which this mean this form instance)

this.Invoke(new Action(delegate(){ /* your Synchronized code comes here */}))
        or (Action)delegate() {} as i saw in internet

Во-вторых, поместите вычисления в фоновый режим, выполните что-то вроде двойной буферизации ... означает, что вы не применяете и не синхронизируете свою форму, пока выполняете вычисления или чертежи ...

, как только вы закончите, вы просто применяете, они нарисованы сзади ....

Таким образом, ваш конечный код будет выглядеть так:

{ //New thread function
    // Calculates
    // Draw arts
    // Synchronize
    this.Invoke((Action)delegate() {
        //Perform Synchronizing Code
        // Apply your drawn image and graphics to your image viewer, aka picture box
    }
    // End of thread, or if you need something extra to be performed afterward...
}

Но если у вас нет доступа к этому компонентному блоку.... попробуйте посмотреть, как выглядит производительность, если вы передадите ей параметры в фоновом режиме, а затем добавите ее в форму?если процесс инициализации компонента ниже, чем изменение графики во время работы, если это выглядело хорошо, продолжайте в том же духе, вызывайте при рисовании в каком-либо компоненте каждое изменение, заставляющее форму перерисовываться, и это приводит к снижению производительности.

0 голосов
/ 14 июня 2019

Взгляните на BackgroundWorker . Это системный компонент, который позволяет многопоточной процедуре выполнять свою работу асинхронно и предоставляет два события обратного вызова (ProgressChanged, RunWorkerCompleted), которые выполняются в потоке пользовательского интерфейса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...