繁体   English   中英

c#中的多线程问题

[英]Multi-threading issue in c#

我试图在我的Windows窗体应用程序中使用Interval计时来绘制数据。

我需要在一个单独的线程上运行图形元素,但我有三个不同的函数被调用,不能简单地使用thread.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);
}

看看BackgroundWorker 它是一个系统组件,允许线程过程异步执行其工作,并提供在UI线程上运行的两个回调事件(ProgressChanged,RunWorkerCompleted)。

有两件事...... 1.窗体使用队列而不是线程,它建立在STA(单线程架构师)事件上,虽然当我们看它时,它看起来像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...
}

但是,如果您无法访问该组件抽屉....尝试查看性能如何,如果您在后台传递参数,然后将其添加到您的表单? 如果初始化组件的处理低于运行时更改图形的处理,如果看起来不错,那么就这样,因为当你绘制某个组件时,每次更改都会导致表单重绘,并且会带来性能损失。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM