C#,我可以检查锁而不试图获取它吗?

时间:2011-02-11 22:30:15

标签: c# multithreading locking

我的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;
}

5 个答案:

答案 0 :(得分:3)

(假设您知道在处理停止后立即显示此通知的竞争条件......)

您可以切换到CountdownEvent。这与ManualResetEvent类似,但也提供CurrentCountIsSet属性,可用于确定是否正在处理某些内容。

答案 1 :(得分:2)

探索Autoresetevents和ManualResetevents。您可以让生成的线程设置事件并检查主线程中的事件以显示消息。

答案 2 :(得分:2)

如果只是通过回调方法设置一个指示主动锁定的某个volaltile bool属性怎么样?

答案 3 :(得分:2)

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被卡住为真。

答案 4 :(得分:-1)

  

正如我想象的那样轻微   它可能会显示的可能性   实际上没有通知   运行

总是有可能发送“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");
    } 
}