仅在值相同时锁定?

Den*_*dei 10 c# multithreading

如果我有一个在我的webservice中编辑数据库的函数,我只想让一个线程一次执行,如果他们试图编辑同一行.

void EditCheck(long checkid)
    {

        if (isCheckCosed)
            throw new Exception("check is already closed");

        //do stuff

        //after i edit my check i want to close it.
        CloseCheck();
    }
Run Code Online (Sandbox Code Playgroud)

我知道我可以锁定整个功能,但随后我失去了性能,因为它几乎从来没有那个不同的线程会尝试编辑相同的检查.

有没有办法只锁定具有相同checkid的其他线程?

UPDATE

我用OleDbConnectionMySqlConnection

OleDbCommand oleDbCommand = AccessTrans != null ?
new OleDbCommand(sql, AccessConn, AccessTrans) : new OleDbCommand(sql, AccessConn); 
oleDbCommand.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)

相同的功能 MySqlCommand

然后我使用正常的INSERT和UPDATE sql命令.并检查交易是否存在.所以如果你想在上层功能中进行交易,这个功能是有效的.

从数据库中读取我会填写 DataTable

OleDbCommand oleDbCommand = AccessTrans != null ? new OleDbCommand(sql, AccessConn, AccessTrans) : new OleDbCommand(sql, AccessConn);
OleDbDataAdapter dAdapter = new OleDbDataAdapter();
dAdapter.SelectCommand = oleDbCommand;
dAdapter.Fill(dTable);
return dTable;
Run Code Online (Sandbox Code Playgroud)

Ser*_*rvy 18

您可以使用a ConcurrentDictionary将每个id映射到可以锁定的对象:

public class Foo
{
    private ConcurrentDictionary<long, object> dictionary = 
        new ConcurrentDictionary<long, object>();

    private void EditCheck(long checkid)
    {
        var key = dictionary.GetOrAdd(checkid, new object());
        lock (key)
        {
            //Do stuff with key
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您将有很多线程只在上面执行只读操作,您可能还想考虑使用 [ReadWriterLock](http://stackoverflow.com/questions/2116957/readerwriterlock-vs-lock) `checkid`,这将让多个线程都对同一个 `checkid` 执行读取操作,但是一旦有人想要写入它就会锁定所有并发读取器。 (2认同)