- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
.net 核心应用程序中的 session 存储要求您先将其转换为字节数组,然后再检索它。与 .net 框架存储相比,这些序列化和反序列化操作的开销正在产生大量开销。在我们的 .Net 框架应用程序中需要 5 毫秒的操作在 .Net 核心中需要 850 毫秒以上。我需要能够以高性能方式从服务器缓存存储和检索相当大量的数据,类似于我们在 .Net 框架中使用 session 化存储的方式。
我们的应用程序使用大量有点大的 ADO.NET 数据表。它们包含数千行和数十列的情况并不少见。过去,我们使用带有 session 存储的 .Net 框架来快速从 session 中检索 ADO.NET 数据表对象。
DataTable dt = new DataTable();
HttpContext.Current.Session["data"] = dt; // store in session
dt = (DataTable)HttpContext.Current.Session["data"]; // retrieve from session
我们也有自己的自定义类,这些类以数据表作为成员。这些类以不同的方式处理数据。我们还从 session 中存储和检索它们。
[Serializable]
MyClass {
public DataTable dt;
}
在我们的 .NET 框架应用程序中,典型的过滤和分页数据请求需要大约 5 毫秒的往返时间。 session 访问非常快,每次 get 和 set 操作的性能损失可以忽略不计。
我们一直在尝试过渡到 .NET Core,它管理 session 的方式有点不同。我无法在 session 中存储和检索任何对象,而是首先必须将其转换为字节数组。我正在使用带有一点逻辑的二进制格式化程序来处理获取和设置操作。下面的代码并不像它应该的那样高效,但到目前为止最大的瓶颈是 retrieveData 方法中的反序列化操作。
Public class SessionManager : ISessionManager
{
private readonly IHttpContextAccessor _contextAccessor;
public SessionManager(IHttpContextAccessor contextAccessor) {
_contextAccessor = contextAccessor;
}
public T get<T>(string key)
{
object data = retrieveData(key);
return data == null ? default(T) : (T)data;
}
public void set(string key, object data)
{
serializeBinary(key, data);
}
public void remove(string key) {
_contextAccessor.HttpContext.Session.Remove(key);
}
private void serializeBinary(string key, object data) {
BinaryFormatter bf = new BinaryFormatter();
using (var ms = new MemoryStream())
{
bf.Serialize(ms, data);
var bytes = ms.ToArray();
_contextAccessor.HttpContext.Session.Set(key, bytes);
}
}
private object retrieveData(string key) {
byte[] data = null;
_contextAccessor.HttpContext.Session.TryGetValue(key, out data);
if (data == null) return null;
using (MemoryStream ms = new MemoryStream(data))
{
IFormatter br = new BinaryFormatter();
return br.Deserialize(ms);
}
}
}
}
用法:
MyClass c;
c.dt = _myRepo.getLotsOfData();
_SessionManager.set("data", c);
c = _SessionManager.get<MyClass>("data");
我们在数据表上执行的相同分页和过滤操作,使用相同的类,需要 850 毫秒到 950 毫秒才能完成,而我们的 .Net 框架应用程序需要 5 毫秒。在 visual studio 中分析性能,反序列化操作占用了大部分时间,仅此操作就耗时 600 毫秒。
我知道其他库(如 protobuf)比二进制格式化程序快得多,这可能是我下一步要去的地方。但是,如果我将反序列化时间降低到300ms甚至200ms,相比.Net Framework我还是损失了很多性能。
在我看来,似乎需要一种不同的缓存策略。有没有一种方法可以在 .Net 核心应用程序中存储和检索数据,而不需要首先对数据进行序列化和反序列化的开销?
最佳答案
Our apps consume a lot of somewhat large ADO.NET datatables. It is not uncommon for them to contain thousands of rows and dozens of columns.
我想我们已经找到问题了:)
建议:
BinaryFormatter
中序列化 DataSet
之前启用 dataSet.RemotingFormat = System.Data.SerializationFormat.Binary;
DataSet
并停止使用BinaryFormatter
;我不是随便说的 - 它们非常昂贵,所以如果数据实际上非常固定,请考虑使用具有不同序列化程序的 POCO 类型 - protobuf 会很多 CPU 和带宽(数据量)效率更高关于c# - 有没有一种方法可以在 .NET Core 中利用 session 化存储而无需二进制序列化程序的开销?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55271866/
我是一名优秀的程序员,十分优秀!