加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

通过缓存,ThreadStatic等降低ASP.NET中的初始化频率

发布时间:2020-12-16 09:37:24 所属栏目:asp.Net 来源:网络整理
导读:我想在多个并发ASP.NET请求中使用一组非线程安全的编码器实例,而不重新初始化它们.如果我不关心初始化成本,我会这样做: public class ResultController { public JsonResult GetResults() { ListMyViewModel items = new ListMyViewModel(); // It obviousl
我想在多个并发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.129ms,而编码本身需要的时间少于.006ms. (仅供参考,编解码器是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单块加密器,没有实例初始化开销,3)反对我的首选项,将外部初始化的加密器传递给每个项目的构造函数,4)实现IEncryptable接口并在填充结果后重新枚举项目,5)执行viewmodel外部的所有加密,在使用viewmodel的任何地方实现.

解决方法

访问HttpContext.Current.Items的性能成本真的是一个问题,或者你只是在猜测?根据您提供的数字和您提出的问题中的数字,然后在链接的问题中的数字不应该是:
? – 对于1000次迭代,单次初始化为6ms,持续时间为129 ms
? – HttpContext在10K迭代中占用0.1ms(在你的情况下为0.01)

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读