簡體   English   中英

C#,我可以檢查鎖而不試圖獲取它嗎?

[英]C#, Can I check on a lock without trying to acquire it?

我在我的c#web應用程序中有一個鎖,它阻止用戶在啟動后運行更新腳本。

我以為我會在我的母版頁中發出通知,讓用戶知道數據還沒有。

目前我這樣鎖定。

protected void butRefreshData_Click(object sender, EventArgs e)
{
    Thread t = new Thread(new ParameterizedThreadStart(UpdateDatabase));
    t.Start(this);
    //sleep for a bit to ensure that javascript has a chance to get rendered
    Thread.Sleep(100);
}


public static void UpdateDatabase(object con)
{
    if (Monitor.TryEnter(myLock))
    {
        Updater.RepopulateDatabase();
        Monitor.Exit(myLock);
    }
    else
    {
        Common.RegisterStartupScript(con, AlreadyLockedJavaScript);
    }
}

我不想這樣做

if(Monitor.TryEnter(myLock))
    Monitor.Exit(myLock);
else
    //show processing labal

正如我想象的那樣,它可能會在實際運行時顯示通知。

有沒有我可以使用的替代方案?

編輯:
大家好,非常感謝您的建議! 不幸的是我無法讓他們工作......但是我將這兩個想法結合起來並提出了我自己的解決方案。 它似乎工作到目前為止,但我必須等待該過程完成...

好吧,這似乎有效,我將Repopule方法分解為它自己的類。

public static class DataPopulation
{
    public static bool IsUpdating = false;
    private static string myLock = "My Lock";
    private static string LockMessage = @"Sorry, the data repopulation process is already running and cannot be stopped. Please try again later. If the graphs are not slowly filling with data please contact your IT support specialist.";
    private static string LockJavaScript = @"alert('" + LockMessage + @"');";
    public static void Repopulate(object con)
    {
        if (Monitor.TryEnter(myLock))
        {
            IsUpdating = true;
            MyProjectRepopulate.MyProjectRepopulate.RepopulateDatabase();
            IsUpdating = false;
            Monitor.Exit(myLock);
        }
        else
        {
            Common.RegisterStartupScript(con, LockJavaScript);
        }
    }
}

掌握我做的

protected void Page_Load(object sender, EventArgs e)
{
    if (DataPopulation.IsUpdating)
        lblRefresh.Visible = true;
    else
        lblRefresh.Visible = false;
}

(假設您知道在處理停止后立即顯示此通知的競爭條件....)

您可以切換到CountdownEvent 這類似於ManualResetEvent ,但也提供CurrentCountIsSet屬性,可用於確定是否正在處理某些內容。

探索Autoresetevents和ManualResetevents。 您可以讓生成的線程設置事件並檢查主線程中的事件以顯示消息。

怎么樣只是通過回調方法設置一個表示活動鎖定的volaltile bool屬性?

butRefreshData_Click()
{
    lock(myLock)
    {
        if (isbusy) {/*tell user*/}
    }
}

UpdateDatabase(object con)
{
    lock(myLock)
    {
        if (isbusy) {/*tell user*/ return;}
        else {isbusy = true;}
    }

    Updater.RepopulateDatabase();

    lock(myLock)
    {
        isBusy = false;
    }
}

注意:您應該將UpdateDatabase包裝在try-finally中,以避免在拋出異常時isBusy被卡住。

正如我想象的那樣,它可能會在實際運行時顯示通知。

總是有可能發送“Working ...”消息,然后立即完成作業。 你有什么應該在邏輯上工作。

public static void UpdateDatabase(object con) 
{ 
    if (Monitor.TryEnter(myLock)) 
    {
       System.Diagnostics.Debug.WriteLine("Doing the work");
        Thread.Sleep(5000); 
        Monitor.Exit(myLock);
        System.Diagnostics.Debug.WriteLine("Done doing the work");
    } 
    else 
    {
        System.Diagnostics.Debug.WriteLine("Entrance was blocked");
    } 
} 

暫無
暫無

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

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