3

ユーザーがC#スレッドをロックする方法が必要です

データオブジェクトがあり、すべてのユーザーに対して新しいインスタンスを作成します。すべてのユーザーには、このオブジェクトを使用する複数のスレッドがあり、IO操作では、このユーザーに対してのみこのオブジェクトインスタンスをロックしたいと思います。単純なロック{}を使用すると、他のユーザーをブロックするために、すべてのオブジェクトインスタンスがロックされます。

簡単な解決策が必要です。

編集

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#スレッドをロックする方法が必要です。データオブジェクトがあり、すべてのユーザーに対して新しいインスタンスを作成します

ユーザーごとに1つのロックを作成します。または、ユーザーがスレッドより長く存在する場合:ユーザーオブジェクトをロックとして使用します。

lock (userOrTheUserObject)
{
    //Do some op
}

すべてのユーザーには、このオブジェクトとIO操作を使用する複数のスレッドがあります

これは、複数のスレッドを作成する代わりに非同期IOを使用する必要があるように聞こえます(効率が低下します)

このユーザーに対してのみこのオブジェクトインスタンスをロックしたいと思います。単純なロック{}を使用すると、他のユーザーをブロックするために、すべてのオブジェクトインスタンスがロックされます。

オブジェクトがすべてのユーザー間で共有されている場合は、を使用してオブジェクトをロックする必要がありますlock。そうでなければ、ロックはあまり効果的ではありません。もう1つの目的は、共有するオブジェクトを再設計することです。

簡単な解決策が必要です。

単純なスレッドソリューションはありません。

于 2013-02-05T06:48:50.267 に答える
3

を使用できますMonitor。このサンプルでは、​​ユーザー1以外のユーザーがDoItメソッドを同時に実行できます。ユーザー1がDoItを実行している間は、誰もそれを入力できません。弱点は、ユーザー2がすでにDoItを実行しているときに、ユーザー1が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 に答える