gpt4 book ai didi

asp.net - 通过缓存、ThreadStatic 等降低 ASP.NET 中的初始化频率

转载 作者:行者123 更新时间:2023-12-01 05:29:47 32 4
gpt4 key购买 nike

我想跨多个并发 ASP.NET 请求使用非线程安全编码器实例池,而无需重新初始化它们。如果我不关心初始化成本,我会这样做:

public class ResultController {
public JsonResult GetResults() {
List<MyViewModel> items = new List<MyViewModel>();
// It obviously does more than this in real life
for(id = 0; id < 1000; id++) {
items.Add(new MyViewModel(id));
}
return Json(items);
}
}

public class MyViewModel() {
public string CodedId { get; set; }
public MyViewModel(int id) {
// This "new" is the concern
CodedId = new ExpensiveToInitializeCodec().InexpensiveEncode(id);
}
}

工作正常。所有本地人,不用担心线程,在我的模型之外没有人需要了解值是编码的。然而,一个快速的性能测试表明,每次初始化大约需要 0.129 毫秒,而编码本身需要不到 0.006 毫秒。 (仅供引用,编解码器是 TripleDESCryptoServiceProvider)。

我想限制初始化成本而不传递预先初始化的对象(例如进入构造函数以提高性能,但破坏关注点分离)。这是我目前所做的,显然在这个简单的例子之外它变得困惑:
public class ResultController {
public JsonResult GetResults() {
List<MyViewModel> items = new List<MyViewModel>();
ExpensiveToInitializeCodec codec = new ExpensiveToInitializeCodec();
for(id = 0; id < 1000; id++) {
items.Add(new MyViewModel(id, codec));
}
return Json(items);
}
}

public class MyViewModel() {
public string CodedId { get; set; }
public MyViewModel(int id, ExpensiveToInitializeCodec codec) {
CodedId = codec.InexpensiveEncode(id);
}
}

我可以利用著名的 ASP.NET 每个请求缓存模式:
public class MyViewModel() {
public string CodedId { get; set; }
public MyViewModel(int id) {
CodedId = ExpensiveToInitializeCodec.Get().InexpensiveEncode(id);
}
}

public class ExpensiveToInitializeCodec {
public static ExpensiveToInitializeCodec Get() {
ExpensiveToInitializeCodec codec = HttpContext.Current.Items["codec"];
if (codec == null) {
codec = new ExpensiveToInitializeCodec();
HttpContext.Current.Items["codec"] = codec;
}
return codec;
}
}

但是在一个紧密的循环中运行仍然很浪费: How much computation is behind a HttpContext.Current call?

似乎每个线程的解决方案可能比每个请求的解决方案更精确。任何与 ASP.NET 请求兼容的建议?

在 ASP 之外但仍在 .NET 空间中,一个人的答案是 ThreadStatic: Using ThreadStatic to replace expensive locals -- good idea? .但是, http://blog.idm.fr/2010/03/aspnet-thread-agility-or-why-threadstatic-should-not-be-used.html显然排除了 ASP.NET 中的解决方案。与我的类似问题 Is there any way to imitate ThreadStatic for use with HttpContext.Current.Items?没有回答。

编辑:如果我确保我的编解码器使用不与 I/O 操作交错,我似乎可以使用 ThreadStatic,但我不确定这有多安全。

我现在达到了,但我想到的其他一些方法包括 1)为具有 EncodedAttribute 的项目提供自定义序列化/反序列化,2)实现我自己的静态 TripleDES 单 block 加密器,没有实例初始化开销,3)反对我的偏好,将外部初始化的加密器传递给每个项目的构造函数,4)实现 IEncryptable 接口(interface)并在填充结果后重新枚举项目,5)执行 View 模型外部的所有加密,在使用 View 模型的任何地方都实现.

最佳答案

访问 HttpContext.Current.Items 的性能成本真的是一个问题,还是您只是在猜测?根据您给出的数字和您给出的问题中的数字以及链接问题中的数字,它不应该是:
- 单次初始化需要 129 毫秒 + 1000 次迭代需要 6 毫秒
- HttpContext 在 10K 次迭代中需要 0.1 毫秒(即在您的情况下为 0.01)

线程静态是一个坏主意。虽然它可能会起作用,但您将来将无法使用异步 Controller 和类似功能。

关于asp.net - 通过缓存、ThreadStatic 等降低 ASP.NET 中的初始化频率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11866116/

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