【发布时间】:2021-06-07 21:23:27
【问题描述】:
我在网上搜索过,我对多线程有点困惑(lock、Monitor.Enter、volatile 等)所以,我没有在这里询问解决方案,而是尝试了一些“自制”的东西关于多线程管理,我想听听你的建议。
这是我的背景:
-我有一个包含静态Dictionary<int,string>的静态类
-我有很多任务(比如说 1000 个)在这个 Dictionary 中每秒阅读
-我有一个另一个任务,它将每 10 秒更新一次 Dictionary。
这是缓存的代码:
public static class Cache
{
public static bool locked = false;
public static Dictionary<int, string> Entries = new Dictionary<int, string>();
public static Dictionary<int, string> TempEntries = new Dictionary<int, string>();
// Called by 1000+ Tasks
public static string GetStringByTaskId(int taskId)
{
string result;
if (locked)
TempEntries.TryGetValue(taskId, out result);
else
Entries.TryGetValue(taskId, out result);
return result;
}
// Called by 1 task
public static void UpdateEntries(List<int> taskIds)
{
TempEntries = new Dictionary<int, string>(Entries);
locked = true;
Entries.Clear();
try
{
// Simulates database access
Thread.Sleep(3000);
foreach (int taskId in taskIds)
{
Entries.Add(taskId, $"task {taskId} : {DateTime.Now}");
}
}
catch (Exception ex)
{
Log(ex);
}
finally
{
locked = false;
}
}
}
这是我的问题:
程序运行,但我不明白为什么 UpdateEntries 方法中的两次“锁定”bool 分配不会生成多线程异常,因为它是由另一个线程“每次”读取的
有没有更传统的方法来处理这个,我觉得这是一种奇怪的方法?
【问题讨论】:
-
“我对多线程(锁、Monitor.Enter、易失性等)有点困惑”,但只有它们才是处理多线程挑战的正确方法。您上面的代码根本不起作用。
-
@LexLi 事实上它有效,哈哈这就是我想了解的:为什么它有效?
-
如果你有时间系统地学习多线程,这里有一个很棒的在线资源:Threading in C#,作者是 Joseph Albahari。为了编写正确的多线程代码,需要对基础有一些扎实的了解。
标签: c# multithreading thread-safety