3

我需要一种方法来按用户锁定 c# 线程

我有我的数据对象,并为每个用户创建新实例。每个用户都有几个使用这个对象的线程,在 IO 操作中我只想为这个用户锁定这个对象实例。使用简单的 Lock {} 锁定所有对象实例,以阻止其他用户。

我需要一些简单的解决方案。

编辑

MyDataObj我为每个用户构建新实例;MyDataObj然后运行每分钟更新一些数据的作业;使用lockObj作为锁,将数据锁定给所有用户(虽然它不是静态变量)我只需要将数据锁定给当前用户

这是代码示例

public sealed class MyDataObj
{
    private static readonly Dictionary<object, MyDataObj> _instances = new Dictionary<object, MyDataObj>();
    public object lockObj = new object();
    public bool jobRunning = false;
    private string data = string.Empty;
    //// --------- constractor -------------------
    private MyDataObj(int key)
    {
        LoadMyDataObj(key);
    }

    public static MyDataObj GetInstance(int key)
    {
        lock (_instances)
        {
            MyDataObj instance;
            if (_instances.TryGetValue(key, out instance))
            {
                instance = _instances[key];
                return instance;
            }
            instance = new MyDataObj(key);
            return instance;
        }
    }

    private void LoadMyDataObj(int key)
    {
        // get the data from db

    }


    public void UpdateMyData(string newData)
    {
        lock (lockObj)
        {
            this.data = newData;
        }
    }
    public string ReadMyData()
    {
        lock (lockObj)
        {
            return this.data;
        }
    }



    public class ActionObject
    {
        MyDataObj myDataObj;
        int UserID;
        //// --------- constractor -------------------
        public ActionObject(int userid)
        {
            this.UserID = userid;
            myDataObj = MyDataObj.GetInstance(userid);
            if (!myDataObj.jobRunning)
            {
                jobs jbs = new jobs(myDataObj);
                System.Threading.Thread RunJob = new System.Threading.Thread(new System.Threading.ThreadStart(jbs.dominutesAssignment));
                RunJob.Start();
                myDataObj.jobRunning = true;
            }
        }
        public ActionObject()
        {
            myDataObj = MyDataObj.GetInstance(this.UserID);
            myDataObj.UpdateMyData("some data");
        }
    }


    public class jobs
    {
        MyDataObj myDataObj = null;

        public jobs(MyDataObj grp)
        {
            this.myDataObj = grp;
        }
        public void dominutesAssignment()
        {
            while (true)
            {
                myDataObj.ReadMyData();
                System.Threading.Thread.Sleep(1000);
            }
        }
    }
}
4

2 回答 2

4

我需要一种方法来按用户锁定 c# 线程。我有我的数据对象,并为每个用户创建新实例

为每个用户创建一个锁。或者如果用户存在的时间比线程长:使用用户对象作为锁。

lock (userOrTheUserObject)
{
    //Do some op
}

每个用户都有多个线程使用这个对象并在 IO 操作中

这听起来更像是您应该使用异步 IO 而不是创建多个线程(这会降低效率)

我只想为这个用户锁定这个对象实例。使用简单的 Lock {} 锁定所有对象实例,以阻止其他用户。

如果该对象在所有用户之间共享,您必须使用lock. 否则锁不会很有效。另一个目标是重新设计现在要共享的对象。

我需要一些简单的解决方案。

没有简单的线程解决方案。

于 2013-02-05T06:48:50.267 回答
3

您可以使用Monitor. 在此示例中,除用户 1 之外的任何人都可以同时执行 DoIt 方法。当用户 1 执行 DoIt 时,没有人可以进入它。一个弱点是如果用户 1 在用户 2 已经执行 DoIt 时尝试执行它,用户 2 会继续执行它。此外,您必须正确处理异常,否则可能会出现死锁。

private static readonly object lockObj = new Object();

public void Do(int userId)
{
     Monitor.Enter(lockObj);

     if (userId != 1)
          Monitor.Exit(lockObj);

     try
     {
        DoIt();
     }
     finally 
     {
         if (userId == 1)
             Monitor.Exit(lockObj);
     }
}

public void DoIt()
{
    // Do It
}
于 2013-02-05T06:33:59.930 回答