不建议使用成员变量
本文关键字:成员 变量 | 更新日期: 2023-09-27 17:51:02
根据MSDN,由于线程和缓存的关系,不建议使用成员变量。请注意,这个问题涉及多个字段,虽然我确定它主要与。net/c#相关,但它可能是特定于CRM的。可能不会,但事先提醒一下可能是明智的。
虽然我对可能出现的问题有一个坚定的把握,但我不能完全确定我理解在警告限制之外的确切和精确的情况。我所关心的确切报价单如下:
为了提高性能,Microsoft Dynamics CRM缓存插件实例。应该将插件的Execute方法编写为无状态的,因为并不是在每次调用插件时都调用构造函数。另外,多个系统线程可以同时执行插件。所有的每次调用状态信息都存储在上下文中,因此您不应该使用全局变量或尝试在成员变量中存储任何数据以供下次插件调用时使用,除非这些数据是从提供给构造函数的配置参数中获得的。对插件注册的更改将导致插件被重新初始化。
我的类是按照以下原则建立的。
public partial class Blopp : IPlugin
{
private IPluginExecutionContext Context { get; set; }
private Entity Target { get; set; }
private IOrganizationService Service { get; set; }
...
public Blopp() : this(String.Empty) { }
public Blopp(String a) : this(a, String.Empty) { }
public Blopp(String a, String b) { ... }
public void Execute(IServiceProvider serviceProvider)
{
try
{
Assign(serviceProvider);
DoStuff();
}
catch (Exception) { }
finally { ... }
}
private void Assign(IServiceProvider serviceProvider) { ... }
}
现在,这个问题可能看起来很愚蠢,但是刚才提到的全局变量—我的私有和非静态字段是全局的吗?我想说他们不是,但我最近有点偏执,我想谦虚一点。
此外,当我访问上下文并Assign字段时,我创建了一个新对象并逐个分配字段(并不是每个类都有Clone方法)。序列化将要求我继承原始类,这是违反要求的。这是一个足够可靠的方法吗?(记住我最近得了妄想症。)
我曾尝试在执行过程中制造问题,但就我所见,问题并未出现。当然,没有证据并不等于没有证据。我只是想指出,我不是在偷懒。比起我一开始所能看到的,我更清楚地意识到事情可能存在更深层次的问题。
不,私有成员不是全局变量。关键是"您不应该使用全局变量或试图将任何数据存储在成员变量中以供下次插件调用时使用"。
它说,如果你在Execute()
中操作你的私有(或全局)变量,Execute()
的另一个调用可能会同时运行在同一个实例上,并覆盖你的私有(或全局)变量,导致之后运行的代码显示意想不到的行为。
所以,让它们成为局部变量:
private void Assign(IServiceProvider serviceProvider)
{
IPluginExecutionContext context;
Entity target;
IOrganizationService service;
...
}
这将确保每个调用堆栈只能访问自己的变量。
要添加到CodeCaster的答案中,您可以拥有的成员变量是通过构造函数初始化的。为了避免状态,它们应该是只读的,所以它们只能由构造函数设置:
public partial class Blopp : IPlugin
{
private readonly string _a;
private readonly string _b;
public Blopp() : this(String.Empty) { }
public Blopp(String a) : this(a, String.Empty) { }
public Blopp(String a, String b)
{
_a = a;
_b = b;
}
您可以从Execute()
中安全地访问_a
和_b