gpt4 book ai didi

c# - 除了 "honor code"之外,使用专用的 "lock object"和直接锁定数据有区别吗?

转载 作者:太空狗 更新时间:2023-10-29 22:00:07 25 4
gpt4 key购买 nike

我有两个线程:一个提供更新,一个将更新写入磁盘。只有最近的更新很重要,所以我不需要 PC 队列。

简而言之:

  • feeder 线程将最新更新放入缓冲区,然后设置标志以指示新更新。
  • 写入线程检查标志,如果它指示新内容,将缓冲的更新写入磁盘并再次禁用标志。

我目前正在使用专用锁对象来确保没有不一致,我想知道这与直接锁定标志和缓冲区有什么区别。我唯一知道的是专用锁对象需要信任每个想要操作标志和缓冲区的人都使用该锁。

相关代码:

private object cacheStateLock = new object();
string textboxContents;
bool hasNewContents;

private void MainTextbox_TextChanged(object sender, TextChangedEventArgs e)
{
lock (cacheStateLock)
{
textboxContents = MainTextbox.Text;
hasNewContents = true;
}
}

private void WriteCache() // running continually in a thread
{
string toWrite;

while (true)
{
lock (cacheStateLock)
{
if (!hasNewContents)
continue;

toWrite = textboxContents;
hasNewContents = false;
}

File.WriteAllText(cacheFilePath, toWrite);
}
}

最佳答案

首先,如果您尝试使用 bool以这种方式标记,您应该将其标记为volatile ( which isn't recommended at all ,但比您的代码更好)。

要注意的第二件事是 lock语句是 Monitor 的语法糖类方法,因此即使您能够为其提供一个值类型(顺便说一下,这是一个编译错误),两个不同的线程将获得他们自己版本的标志,使 lock无用。所以you must provide a reference type for lock statement .

第三件事是strings are immutable in the C# 所以从理论上讲,某些方法可以存储对字符串的旧引用并执行 lock以错误的方式。字符串也可以变成 null来自 MainTextbox.Text在你的情况下,这将在运行时抛出,与 private 相比永远不会改变的对象(顺便说一句,你应该将其标记为 readonly)。

因此,引入专用同步对象是将锁定与实际逻辑分开的最简单自然的方法

至于你的初始代码,它有一个问题,如MainTextbox_TextChanged可以覆盖未写下的文本。您可以在此处引入一些额外的同步逻辑或使用一些库。 @Aron 建议 Rx 在这里,我个人更喜欢 TPL Dataflow ,没关系。

您可以添加 BroadcastBlock链接到 ActionBlock<string>(WriteCache) , 这将从 WriteCache 中删除无限循环方法和 lock从你的两种方法:

var broadcast = new BroadcastBlock<string>(s => s);
var consumer = new ActionBlock<string>(s => WriteCache(s));
broadcast.LinkTo(consumer);

// fire and forget
private async void MainTextbox_TextChanged(object sender, TextChangedEventArgs e)
{
await broadcast.SendAsync(MainTextbox.Text);
}

// running continually in a thread without a loop
private void WriteCache(string toWrite)
{
File.WriteAllText(cacheFilePath, toWrite);
}

关于c# - 除了 "honor code"之外,使用专用的 "lock object"和直接锁定数据有区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41539964/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com