gpt4 book ai didi

c# - 如何在 C# 中的多命令模式中与不同线程共享相同的上下文?

转载 作者:可可西里 更新时间:2023-11-01 09:14:09 25 4
gpt4 key购买 nike

command pattern 的扩展实现支持 C# 中的多命令(组):

var ctx= //the context object I am sharing...

var commandGroup1 = new MultiItemCommand(ctx, new List<ICommand>
{
new Command1(ctx),
new Command2(ctx)
});

var commandGroup2 = new MultiItemCommand(ctx, new List<ICommand>
{
new Command3(ctx),
new Command4(ctx)
});

var groups = new MultiCommand(new List<ICommand>
{
commandGroup1 ,
commandGroup2
}, null);

现在,执行是这样的:

groups.Execute();

我正在共享相同的上下文 (ctx) 对象。

web app的执行计划需要分开commandGroup1commandGroup2 分组在不同的线程中。具体来说,commandGroup2会在新线程中执行,commandGroup1会在主线程中执行。

执行现在看起来像:

//In Main Thread
commandGroup1.Execute();

//In the new Thread
commandGroup2.Execute();

如何线程安全共享同一个context object (ctx),以便能够回滚commandGroup1新主题?

t.Start(ctx); 是否足够,还是我必须使用锁或其他东西?

一些代码实现示例是here

最佳答案

所提供的示例代码肯定会留下大量关于您的特定用例的问题;但是,我将尝试回答在多线程环境中实现此类问题的一般策略。

上下文或其数据是否以耦合的、非原子的方式被修改?

例如,您的任何命令是否会执行以下操作:

Context.Data.Item1 = "Hello"; // Setting both values is required, only
Context.Data.Item2 = "World"; // setting one would result in invalid state

那么您绝对需要在代码中的某处使用 lock(...) 语句。问题是在哪里。

嵌套 Controller 的线程安全行为是什么?

在链接的 GIST 示例代码中,CommandContext 类具有属性 ServerControllerServiceController。如果您不是这些类的所有者,那么您还必须仔细检查有关这些类的线程安全性的文档。

例如,如果您在两个不同线程上运行的命令执行如下调用:

Context.ServiceController.Commit();   // On thread A

Context.ServiceController.Rollback(); // On thread B

如果 Controller 类的创建者不期望多线程使用,则很有可能无法同时调用这两个操作。

何时锁定以及锁定什么

每当您需要执行多个必须完全发生或根本不发生的操作时,或者在调用不需要并发访问的长时间运行的操作时,请获取锁。尽快释放锁。

此外,只应对只读或常量属性或字段进行锁定。所以在你做类似的事情之前:

lock(Context.Data)
{
// Manipulate data sub-properties here
}

请记住,可以换出 Data 指向的对象。最安全的实现是提供一个特殊的锁定对象:

internal readonly object dataSyncRoot = new object();
internal readonly object serviceSyncRoot = new object();
internal readonly object serverSyncRoot = new object();

对于需要独占访问和使用的每个子对象:

lock(Context.dataSyncRoot)
{
// Manipulate data sub-properties here
}

对于何时何地进行锁定没有 Elixir ,但一般来说,将它们放在调用堆栈的较高位置,您的代码可能会更简单和更安全,但会牺牲性能 - 因为两者线程不能再同时执行。将它们放置得越靠下,代码的并发性就越高,但开销也越大。

另外:实际获取和释放锁几乎没有性能损失,因此无需担心。

关于c# - 如何在 C# 中的多命令模式中与不同线程共享相同的上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37889973/

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