簡體   English   中英

如何在C#中鎖定單個線程

[英]How can I lock a single thread in C#

我想將資源“鎖定”在單個線程上。 我已經嘗試了所有可以想到的鎖定機制,但是無法完成這項工作。

在下面的示例中,當計時器觸發時,我不希望DoSomething中的代碼執行到ShowDialog返回之前。 我希望lock語句只允許返回Form2的一個實例,但是實際上它全部在一個線程上運行,因此它不會阻止線程重新進入該代碼塊。

這是一些示例代碼,這不是我要面對的確切情況,但是它說明了問題。 在我的實際代碼中,我從連接的設備接收事件,因此沒有計時器。

若要重現,請創建Windows Forms應用程序並添加Form1和Form2。 將此代碼復制到Form1中:

public partial class Form1 : Form
{
    Timer _timer = new Timer();
    private static object _lock = new object();

    public Form1()
    {
        InitializeComponent();

        _timer.Tick += delegate { DoSomething(); };
        _timer.Interval = 5000;
        _timer.Start();
    }

    private void DoSomething()
    {
        lock (_lock)
        {
            Form2 form2 = new Form2();
            form2.ShowDialog();
        }
    }
}

如果使用ThreadStaticAttribute ,則標記應可以解決問題。

public partial class Form1 : Form
{
    Timer _timer = new Timer();
    [ThreadStatic]
    bool inEvent = false;

    public Form1()
    {
        InitializeComponent();

        _timer.Tick += delegate { DoSomething(); };
        _timer.Interval = 5000;
        _timer.Start();
    }

    private void DoSomething()
    {
        // if you want to stay here and wait instead of exiting, you could do:
        // while (inEvent);
        if (!inEvent)
        {
            inEvent = true;
            Form2 form2 = new Form2();
            form2.ShowDialog();
            inEvent = false;
        }
    }
}

您是否不能創建表單的一個實例,將其存儲在類變量中,然后使用check的Visible屬性?

http://msdn.microsoft.com/zh-CN/library/system.windows.forms.control.visible.aspx

public partial class Form1 : Form
{
    Timer _timer = new Timer();
    Form2 form2 = new Form2();

    public Form1()
    {
        InitializeComponent();

        _timer.Tick += delegate { DoSomething(); };
        _timer.Interval = 5000;
        _timer.Start();
    }

    private void DoSomething()
    {
        if(!form2.Visible)
        {
           form2.ShowDialog();
        }
    }
}

肖恩,聽起來其他人沒有解決您的實際問題。 看起來您在通過簡單的解決方案提出了一個更大的問題。 無論如何,鎖不會最終在同一線程上工作。 它用於阻止其他線程。 如果在同一線程上遇到鎖,則它只會增加引用計數或其他內容,並且僅允許條目阻塞其他線程,直到引用計數變為零為止。

因此,最初我以為Mutex,Semaphore,SpinWait,SpinUntil會有所幫助,但是盡管它們最終會阻止滿足您阻止輸入的需求,但是由於您在UI線程上,因此您的應用程序隨后被鎖定並等待,因此您贏得了甚至無法關閉Form2(或您要處理的任何內容)。

老實說,我不知道解決問題的正確方法。 我認為會有某種模式或內置功能可以做到這一點,但我沒有意識到。 但是,如果您可以創建另一個線程,則可以解決您的問題,如下面的代碼所示。

public partial class Form1 : Form
{
    Timer _timer = new Timer();
    private readonly static object _lock = new object();

    public Form1()
    {
        InitializeComponent();

        _timer.Tick += delegate { OnTimerTick(); };
        _timer.Interval = 5000;
        _timer.Start();
    }

    private void OnTimerTick()
    {
        new System.Threading.Thread (DoSomething).Start();
    }

    private void DoSomething()
    {
        Console.WriteLine("Before Lock");

        lock(_lock)
        {
            // Do stuff...

            Form2 form2 = new Form2();
            form2.ShowDialog();

        }

        Console.WriteLine("After Lock");
    }
}

祝好運。 如果這樣做有幫助,請不要忘記投票給這個答案。

謝謝湯姆

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM