-
Notifications
You must be signed in to change notification settings - Fork 453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LinqToDB.Reflection.TypeAccessor1[[System.__Canon, mscorlib]]..cctor() wait long System.Linq.Expressions.Expression
1[[System.__Canon, mscorlib]].Compile()
#3650
Comments
I think just call stack is not enough. Show Model classes and LINQ query. Also remove from issue not relevant issues template text. Also 2.9.x version is no longer supported. Check on the latest linq2db version. |
I Checked on the latest linq2db version , the code of LinqToDB.Reflection.TypeAccessor was not changed. |
I do not ask to check TypeAccessor code, check that your issue still exists in latest linq2db release. |
I mean, the static constructor of LinqToDB.Reflection.TypeAccessor first compiles the lamda for a long time。later ,this LambdaCompiler of the same lamda will be locked .this issue still exists |
Show your LINQ query and model. |
var currentOffOn = (from p in db.TMS_USER_ONOFF
where p.ENTERPRISE_ID == enterpriseId && p.PARK_ID == parkAndPerson.park.ID && p.STATUS == "ON" && p.PERSON_CODE == parkAndPerson.person.PERSON_CODE
select p into a
select new { a.DATETIME_CREATED, a.PERSON_STATUS, a.JOB_TYPE, a.TASK_WAREHOUSE } into p
orderby p.DATETIME_CREATED descending
select p).FirstOrDefault();
parameterExpression = Expression.Parameter(typeof(TMS_USER_ONOFF), "a");
var source2 = source.Select(Expression.Lambda(Expression.New(methodof(<>f__AnonymousType202<DateTime?, string, string, string>..ctor(<DATETIME_CREATED>j__TPar, <PERSON_STATUS>j__TPar, <JOB_TYPE>j__TPar, <TASK_WAREHOUSE>j__TPar)), new Expression[]
{
Expression.Property(parameterExpression, methodof(ModelBase.get_DATETIME_CREATED())),
Expression.Property(parameterExpression, methodof(TMS_USER_ONOFF.get_PERSON_STATUS())),
Expression.Property(parameterExpression, methodof(TMS_USER_ONOFF.get_JOB_TYPE())),
Expression.Property(parameterExpression, methodof(TMS_USER_ONOFF.get_TASK_WAREHOUSE()))
}, new MemberInfo[]
{
methodof(<>f__AnonymousType202<DateTime?, string, string, string>.get_DATETIME_CREATED()),
methodof(<>f__AnonymousType202<DateTime?, string, string, string>.get_PERSON_STATUS()),
methodof(<>f__AnonymousType202<DateTime?, string, string, string>.get_JOB_TYPE()),
methodof(<>f__AnonymousType202<DateTime?, string, string, string>.get_TASK_WAREHOUSE())
}), new ParameterExpression[]
{
parameterExpression
}));
parameterExpression = Expression.Parameter(typeof(<>f__AnonymousType202<DateTime?, string, string, string>), "p");
CS$<>8__locals4.currentOffOn = source2.OrderByDescending(Expression.Lambda(Expression.Property(parameterExpression, methodof(<>f__AnonymousType202<DateTime?, string, string, string>.get_DATETIME_CREATED())), new ParameterExpression[]
{
parameterExpression
})).FirstOrDefault(); 3) windbg
3)linqtodb code public class TypeAccessor<T> : TypeAccessor
{
static TypeAccessor()
{
// Create Instance.
//
var type = typeof(T);
if (type.IsValueTypeEx())
{
_createInstance = () => default;
}
else
{
var ctor = type.IsAbstractEx() ? null : type.GetDefaultConstructorEx();
if (ctor == null)
{
Expression<Func<T>> mi;
if (type.IsAbstractEx()) mi = () => ThrowAbstractException();
else mi = () => ThrowException();
var body = Expression.Call(null, ((MethodCallExpression)mi.Body).Method);
_createInstance = Expression.Lambda<Func<T>>(body).Compile();
}
else
{
_createInstance = Expression.Lambda<Func<T>>(Expression.New(ctor)).Compile();
}
} |
Add |
internal class TMS_USER_ONOFF
{
public string PARK_ID { get; set; }
public string TASK_WAREHOUSE { get; set; }
public string PERSON_CODE { get; set; }
public string JOB_TYPE { get; set; }
public string STATUS { get; set; }
public string PERSON_STATUS { get; set; }
public DateTime DATETIME_ON { get; set; }
public DateTime? DATETIME_OFF { get; set; }
public decimal? HOUR_ON { get; set; }
public TMS_USER_ONOFF()
{
base.STATE = "A";
}
} |
From the dump file, the 10 threads in the above figure are similar, all of which are different lamda expressions entering the static constructor, blocking different numbers of threads. Currently, there is a balance between reducing lamda compilation without blocking the running of the same lamda thread. In this case, the caller can decide what strategy to use. At present, my application is found because LinqToDB.Reflection.TypeAccessor blocks hundreds of threads, and at the same time, new 900 DbNorthwind (LinqToDB.Data.DataConnection) objects are created, resulting in the mysql database connection pool being allocated, causing the entire application to fail to work. |
It is something weird, it should be handled by .NET Runtime correctly, but it's not. It would good to have some kind of small testing app which reproduces problem. |
If can't reduce the blocking caused by lamda expression compilation, it is best to optimize it. Do not use LinqToDB.Data.DataConnection before compilation, because the number of connection objects in the data connection pool is limited. Because LinqToDB.Data.DataConnection is used up due to blocking caused by lamda expression compilation, the entire application hangs. |
Describe your issue.
If you have a question, first try to check our documentation, especially FAQ and search in issues and discussions - maybe your question already answered there.
If you still have questions or want to start general discussion, please create new topic in discussions.
If you are seeing an exception, include the full exceptions details (message and stack trace).
Environment details
linq2db version: 2.9.6
Database Server: mysql
Database Provider: MySql.Data.dll
Operating system: windows server 2016
.NET Framework: 4.8.1
The text was updated successfully, but these errors were encountered: