c#多个事件的多重锁定

时间:2016-07-13 08:27:21

标签: c# events locking

我正在尝试理解锁定机制。 如果我有多个事件来锁定不同的值我应该为每个使用一个对象锁吗? 更严重的代码添加:

 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Data;
 using System.Drawing;
 using System.Linq;
 using System.Text;
 using System.Windows.Forms;
 using System.IO;
 using System.Threading;

 namespace ValueChangeOnEventForm
 {

public partial class Form1 : Form
{
    private Test_Onchange DataSource;
    Thread Task1;
    private bool Flag_Stop_Task1;
    public Form1()
    {
        InitializeComponent();
        graph1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
        graph1.ChartAreas[0].AxisX.IsLabelAutoFit = true;
        graph1.ChartAreas[0].AxisX.ScaleView.Size = 100;
        graph2.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
        graph2.ChartAreas[0].AxisX.IsLabelAutoFit = true;
        graph2.ChartAreas[0].AxisX.ScaleView.Size = 100;

        DataSource = new Test_Onchange();
        DataSource.ValueChanged += new   EventHandler(EventValueChange);//Value input info
        DataSource.SecondValueChange += new EventHandler(EventSecondValueChange);//second value

        Task1 = new Thread(new ThreadStart(Task_1));//create the thread
        Task1.Start();//start the thread
    }
    protected virtual void EventSecondValueChange(object sender, EventArgs e)
    {
        double valueMAX = 0, size = 0;

        if (graph1.InvokeRequired)
        {
            graph1.Invoke(new MethodInvoker(delegate { graph1.Series["ValueOnGraph"].Points.AddY(DataSource.Value); }));
            graph1.Invoke(new MethodInvoker(delegate { valueMAX = graph1.ChartAreas[0].AxisX.Maximum; }));
            graph1.Invoke(new MethodInvoker(delegate { size = graph1.ChartAreas[0].AxisX.ScaleView.Size; }));
            if (valueMAX - 10 > size)
            {
                graph1.Invoke(new MethodInvoker(delegate { graph1.ChartAreas[0].AxisX.ScaleView.Scroll(graph1.ChartAreas[0].AxisX.Maximum); }));
                graph1.Invoke(new MethodInvoker(delegate { graph1.Series["ValueOnGraph"].Points.RemoveAt(0); }));
            }
        }
    }
    protected virtual void EventValueChange(object sender, EventArgs e)
    {
        double valueMAX=0,size=0;

        if (graph2.InvokeRequired)
        {
            graph2.Invoke(new MethodInvoker(delegate { graph2.Series["ValueOnGraph2"].Points.AddY(DataSource.Secondvalue); }));
            graph2.Invoke(new MethodInvoker(delegate { valueMAX = graph2.ChartAreas[0].AxisX.Maximum; }));
            graph2.Invoke(new MethodInvoker(delegate { size = graph2.ChartAreas[0].AxisX.ScaleView.Size; }));
            if (valueMAX - 10 > size)
            {
                graph2.Invoke(new MethodInvoker(delegate { graph2.ChartAreas[0].AxisX.ScaleView.Scroll(graph2.ChartAreas[0].AxisX.Maximum); }));
                graph2.Invoke(new MethodInvoker(delegate { graph2.Series["ValueOnGraph2"].Points.RemoveAt(0); }));
            }
        }
    }
    private void Task_1()
    {
        while (!Flag_Stop_Task1)
        {
            Random RandVal = new Random();
            Random RandVal2 = new Random();

            int Value = RandVal.Next(0, 100);
            int SecondValue = RandVal2.Next(50, 200);

            DataSource.Value = Value;
            DataSource.Secondvalue = SecondValue;
            Thread.Sleep(100);
        }
        Flag_Stop_Task1 = false;
    }

    private void btn_StopTask_1_Click(object sender, EventArgs e)
    {
        Flag_Stop_Task1 = true;
    }
}   
}

然后

 namespace ValueChangeOnEventForm
 {
 class Test_Onchange
 {
    private int value;
    private int secondvalue;

    protected object _lock = new object();

    public event System.EventHandler ValueChanged;
    public event System.EventHandler SecondValueChange;

    protected virtual void OnValueChange()
    {  
        lock (this._lock)
        {
        EventHandler eventvaluechange = ValueChanged;
            if (eventvaluechange != null)
                eventvaluechange(this, EventArgs.Empty);
        }
    }
    protected virtual void OnSecondValueChange()
    {
        lock (this._lock)
        {
            EventHandler eventvaluechange = SecondValueChange;
            if (eventvaluechange != null)
                eventvaluechange(this, EventArgs.Empty);
        }
    }

    public int Value
    {
        get { return this.value; }
        set
        {
            if (value != this.value)
            {//if value changed enter
                this.value = value;
                OnValueChange();
            }
        }
    }
    public int Secondvalue
    {
        get { return this.secondvalue; }
        set
        {
            if (value != this.secondvalue)
            {//if value changed enter
                this.secondvalue = value;
                OnSecondValueChange();
            }
        }        
    }
   }
   }

我需要两个锁(lock1和lock2对象,还是只需要一个值和第二个值....? 非常感谢。

更新

好的,让我们这样做。 我正在使用beckhoff PLC,它是实时任务PLC。当值改变时,我正在读取两个值。像这样: Form1类:

 namespace RealTimeLock
 {
   using Beckhoff.App.Ads.Core;
   using Beckhoff.App.Ads.Core.Plc;
   using TwinCAT.Ads;
   using System.IO;  
public partial class Form1 : Form
{
    private PLC PLCData;
    public Form1()
    {
        InitializeComponent();
    }

    public Form1(IBAAdsServer _adsServer)
        : this()
    {
        PLCData = new PLC(_adsServer);

        PLCData.ErrorBoolChanged += new EventHandler(EventErrorChanged);//error info
        PLCData.ForceValChanged += new EventHandler(EventForceChanged);//Force input info
    }
    protected virtual void EventErrorChanged(object sender, EventArgs e)
    {
        //state of error PLC
        lv_ErrorInfo.Text = "PLC Error num : " + PLCData.i_ErrorID.ToString();
    }
    protected virtual void EventForceChanged(object sender, EventArgs e)
    {//modify graphical data PLC Force data
        lv_ForceInfo.Text = PLCData.i_ForceVal.ToString();
        c_graphForceIN.Series["ForceData"].Points.AddY(PLCData.i_ForceVal);
        if (c_graphForceIN.ChartAreas[0].AxisX.Maximum - 10 > c_graphForceIN.ChartAreas[0].AxisX.ScaleView.Size)
        {
            c_graphForceIN.ChartAreas[0].AxisX.ScaleView.Scroll(c_graphForceIN.ChartAreas[0].AxisX.Maximum);
            c_graphForceIN.Series["ForceData"].Points.RemoveAt(0);
        }
    }
}
}

错误ID和强制更改显示在Form1标签lv_ErrorID和lv_Force以及graphForceIN添加点。

另一侧的事件处理程序(PLC类)如下所示: PLC类:

 namespace RealTimeLock
  {
  using Beckhoff.App.Ads.Core;
  using Beckhoff.App.Ads.Core.Plc;
  using TwinCAT.Ads;
  using System.IO;  
public partial class Form1 : Form
{
    private PLC PLCData;
    public Form1()
    {
        InitializeComponent();
    }

    public Form1(IBAAdsServer _adsServer)
        : this()
    {
        PLCData = new PLC(_adsServer);

        PLCData.ErrorBoolChanged += new EventHandler(EventErrorChanged);//error info
        PLCData.ForceValChanged += new EventHandler(EventForceChanged);//Force input info
    }
    protected virtual void EventErrorChanged(object sender, EventArgs e)
    {
        //state of error PLC
        lv_ErrorInfo.Text = "PLC Error num : " + PLCData.i_ErrorID.ToString();
    }
    protected virtual void EventForceChanged(object sender, EventArgs e)
    {//modify graphical data PLC Force data
        lv_ForceInfo.Text = PLCData.i_ForceVal.ToString();
        c_graphForceIN.Series["ForceData"].Points.AddY(PLCData.i_ForceVal);
        if (c_graphForceIN.ChartAreas[0].AxisX.Maximum - 10 > c_graphForceIN.ChartAreas[0].AxisX.ScaleView.Size)
        {
            c_graphForceIN.ChartAreas[0].AxisX.ScaleView.Scroll(c_graphForceIN.ChartAreas[0].AxisX.Maximum);
            c_graphForceIN.Series["ForceData"].Points.RemoveAt(0);
        }
    }
}
}

对你们来说,这似乎是正确的编码吗?虽然我有一个实时任务在那里运行,我需要锁定变量,如果是这样,我需要两个锁或只有一个? 感谢您对此的评论!!

0 个答案:

没有答案