kom*_*bsh 1 c# multithreading locking
我正在使用 C# 锁来阻止代码执行。如果我们在 Lock 中使用动态字符串输入,它是行不通的。
public class ParameterClass
{
public string A = string.Empty;
public Int64 B = 0;
}
class Program
{
static void Main(string[] args)
{
ParameterClass parm = new ParameterClass { A = "Test", B = 1 };
Thread thread = new Thread(ThreadFun);
thread.Start(parm);
System.Threading.Thread.Sleep(2000);
parm = new ParameterClass { A = "Test", B = 1 };
ThreadFun(parm);
}
public static void ThreadFun(object para)
{
ParameterClass parameter = (ParameterClass)para;
lock (parameter.B.ToString())
{
Console.WriteLine(DateTime.Now);
System.Threading.Thread.Sleep(20000);
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我将 Thread.Sleep(20000) - 20 秒放入 Lock 语句中。我的预期结果是应该根据参数锁定代码块。B ...
任何人都可以帮助我继续吗?
您的代码锁定等效于以下内容,因为ToString()通常在每次调用时都会创建新字符串:
lock(new object()) { ... }
Run Code Online (Sandbox Code Playgroud)
由于每次锁定不同的对象,这显然不会阻止其他线程执行相同的代码块。
您想锁定以某种方式与在受保护块中访问的数据相关的对象。在你的情况下,如果它在执行过程中没有改变,它可能是它para本身或内部的其他引用类型值parameter(B不能使用值类型):
lock(para)
{....}
Run Code Online (Sandbox Code Playgroud)
请注意,如果使用特殊的“锁定”私有对象来保护通过同一类的方法对数据的访问,则推荐方法...
通过lock以下方式保护对 2 个属性的访问的类示例:
public class ParameterClass
{
private object lockObject = new object();
private string a = string.Empty;
private Int64 b = 0;
public SafeSet(string v, long number)
{
lock(lockObject)
{
a = v;
b = number;
}
}
public string A
{
get { lock(lockObject) { return a; } }
}
public long B
{
get { lock(lockObject) { return b; } }
}
}
Run Code Online (Sandbox Code Playgroud)
如果您需要锁定一根绳子,您可以string.Intern在该绳子上使用。这样做可以锁定字符串引用。
lock (string.Intern(parameter.B.ToString()))
{ ... }
Run Code Online (Sandbox Code Playgroud)
但请注意这允许什么,与传统的锁对象 ( private readonly object) 不同,这种类型的锁可以在代码中的任何位置使用,可能会导致同步问题或死锁。