线程竞争和锁定关键字

时间:2013-11-29 03:36:39

标签: c# multithreading locking

我的应用程序有一个登录区域,使用线程访问数据库,不会冻结UI。

在登录期间,系统进行一些操作以打开主窗口,并在另一个线程中加载用户数据(和权限)。

但有时,当数据库挂起时,系统会在加载用户之前完成加载。

系统执行的最后一个操作是应用权限(在线程中加载用户的数据)。

我还有一个静态User对象,用于保存登录用户的数据,如权限等。

当应用程序在加载用户之前从静态用户对象获取数据时,会发生此问题。权限为空,未正确应用,从而导致意外行为。

如何确保加载静态用户,并且只会在网络/数据库延迟极端情况下冻结UI?

我尝试使用lock,但它根本不起作用。

这是我的代码:

int id = User.GetId(user, password); // returns 0 if the user does not exists

if (id != 0)
{
     new Thread(() => 
     {
          lock (User.CurrentUser) // Try to lock the static CurrentUser object
          { 
              User.LoadCurrentUser(id);  // Loads the CurrentUser object
          }

      }).Start();

      InitializeSystem(); //Make some work on the system. After that, this
                          //will get the User.CurrentUser object to apply the
                          //user's permissions.
  }

方法User.LoadCurrentUser(id);填充用户。

我知道锁无法正常工作,因为我在锁中放了Thread.Sleep(5000);,系统在2秒内以错误的权限启动。

不考虑删除线程,因为它会破坏我的UI。

修改

我需要使用.Net Framework 4.0来确保Windows XP的兼容性。

2 个答案:

答案 0 :(得分:1)

这是await或链式任务的完美候选者。

等待版本:

async void YourLoginButtonEventHandler() {
    int id = User.GetId(user, password); // returns 0 if the user does not exists

    if (id != 0) {
        await Task.Run(() => User.LoadCurrentUser(id));  // Loads the CurrentUser object
        InitializeSystem();
    }
}

或者你可以链接它们:

if (id != 0) {
    Task.Run(() => User.LoadCurrentUser(id))
        .ContinueWith(t => InitializeSystem(), TaskScheduler.FromCurrentSynchronizationContext);
}

注意:可能是一些语法错误..我直接在这里打字。

我基本上想要告诉你的是......你正在努力解决这个问题。对于这种事情有更新的构造..学习它们:))

答案 1 :(得分:0)

您可以使用Thread.Join阻止主线程,直到另一个线程完成或超时。

int id = User.GetId(user, password); // returns 0 if the user does not exists

if (id != 0)
{
 var newThread = new Thread(() => 
 {
      lock (User.CurrentUser) // Try to lock the static CurrentUser object
      { 
          User.LoadCurrentUser(id);  // Loads the CurrentUser object
      }

  }).Start();

  InitializeSystem(); 

  if (newThread.Join(someTimeOut))
     // use the User.CurrentUser object to apply the user's permissions.
  else
     // thread timed out, waiting for user load takes too long...

 }
相关问题