zoukankan      html  css  js  c++  java
  • MethodImpl同步方法

    同步方法

         多线程开发的时候,开发者经常会遇到在一个方法里锁定和释放一个对象的情景,本文演示了如何使用MethodImpl属性标识一个需要同步的方法,让编译器自动产生同步代码。

    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Drawing;
    using System.Threading;
    using System.Windows.Forms;

    public class MyClass
    {        
        [System.Runtime.CompilerServices.MethodImpl(
            System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
        
    public void SetCounter(int counter)
        
    {
            
    this.Counter = counter;
        }

        
        [System.Runtime.CompilerServices.MethodImpl(
            System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
        
    public int GetCounter()
        
    {
            
    return this.Counter;
        }

        
        
    protected string m_CountingString;
        
    protected int Counter
        
    {
            
    set
            
    {
                m_CountingString 
    = "";
                m_CountingString 
    = value.ToString();
            }

            
    get
            
    {
                
    return Convert.ToInt32(m_CountingString);
            }

        }

        
        
    public MyClass()
        
    {
            m_CountingString 
    = "0";
        }

    }


    public class MyForm : System.Windows.Forms.Form
    {
        
    public static void Main()
        
    {
            
    try
            
    {
            Application.Run(
    new MyForm());
            }

            
    catch(Exception ex)
            
    {
                Console.WriteLine(ex.ToString());
                Console.ReadLine();
            }

        }


        
    private Button m_CreateThreads;
        
    private Label m_CounterLabel;
        
    protected MyClass m_MyClass;
        
        
    public MyForm()
        
    {
            
    this.m_CreateThreads = new System.Windows.Forms.Button();
            
    this.m_CreateThreads.Location = new System.Drawing.Point(3232);
            
    this.m_CreateThreads.Name = "CreateThreads";
            
    this.m_CreateThreads.Size = new System.Drawing.Size(11223);
            
    this.m_CreateThreads.TabIndex = 0;
            
    this.m_CreateThreads.Text = "Create Threads";        
            
    this.m_CreateThreads.Click += new System.EventHandler(this.OnCreateThreads);
            
            
    this.m_CounterLabel = new System.Windows.Forms.Label();
            
    this.m_CounterLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
            
    this.m_CounterLabel.ForeColor = System.Drawing.Color.Red;
            
    this.m_CounterLabel.Location = new System.Drawing.Point(3280);
            
    this.m_CounterLabel.Name = "m_CounterLabel";
            
    this.m_CounterLabel.Size = new System.Drawing.Size(12864);
            
    this.m_CounterLabel.TabIndex = 1;
            
    this.m_CounterLabel.Text = "0";
            
            
    this.ClientSize = new System.Drawing.Size(248165);
            
    this.Controls.AddRange(new System.Windows.Forms.Control[] 
                
    {
                    
    this.m_CreateThreads,
                    
    this.m_CounterLabel
                }
    );
            
    this.Text = "SynchMethod";
             
            m_MyClass 
    = new MyClass();
            m_CounterLabel.Text 
    = m_MyClass.GetCounter().ToString();
        }

        
        
    private void OnCreateThreads(object sender,EventArgs e)
        
    {
            ThreadStart threadStart1 
    = new ThreadStart(IncrementCounter);
            Thread thread1 
    = new Thread(threadStart1);
            thread1.IsBackground 
    = true;
            thread1.Start();
            
            ThreadStart threadStart2 
    = new ThreadStart(UpdateCounter);
            Thread thread2 
    = new Thread(threadStart2);
            thread2.IsBackground 
    = true;
            thread2.Start();
        }

        
        
    private void ChangeLabel()
        
    {
            
    if (InvokeRequired)
            
    {
                
    this.Invoke(new MethodInvoker(ChangeLabel));
                
    return;
            }

            
    this.m_CounterLabel.Text = m_MyClass.GetCounter().ToString();
        }

        
        
    protected void IncrementCounter()
        
    {
            
    while(true)
            
    {
                
    int counter = m_MyClass.GetCounter();
                counter
    ++;
                Console.WriteLine(
    "IncrementCounter:{0}", counter);
                m_MyClass.SetCounter(counter);
                Thread.Sleep(
    300);
            }

        }

        
        
    protected void UpdateCounter()
        
    {
            
    while(true)
            
    {
                Console.WriteLine(
    "UpdateCounter");
                
    this.ChangeLabel();
                Thread.Sleep(
    300);
            }

        }

    }

    我们使用ildasm看看编译器对MyClass.GetCounter方法产生的代码:

    .method public hidebysig instance int32  GetCounter() cil managed synchronized
    {
      
    // 代码大小       12 (0xc)
      .maxstack  1
      .locals init ([
    0] int32 CS$1$0000)
      IL_0000:  nop
      IL_0001:  ldarg.
    0
      IL_0002:  call       instance int32 MyClass::get_Counter()
      IL_0007:  stloc.
    0
      IL_0008:  br.s       IL_000a
      IL_000a:  ldloc.
    0
      IL_000b:  ret
    // end of method MyClass::GetCounter
  • 相关阅读:
    【博客大赛】使用LM2677制作的3V至24V数控可调恒压源
    电压跟随器
    运算放大器虚短和虚断
    JTAG TAP Controller
    JTAG Pinouts
    USB Mass Storage Class – Bulk Only Transport
    Send custom commands to Mass Storage device
    USB Mass Storage communication with PassThrough / more than 64K data length
    STLink download/debug interface for Linux.
    SCSI Pass-Through Interface Tool
  • 原文地址:https://www.cnblogs.com/hcfalan/p/504880.html
Copyright © 2011-2022 走看看