Activities of "heshengli"

Answer

是否考虑添加OneTime.Run(),初始化全部用户角色权限,在权限多的情况下,Cache.SetManyAsync比较耗时 也可以添加Options开关

Answer

[maliming] said:

var permissions = (await PermissionDefinitionManager.GetPermissionsAsync()) 
                .Where(x => notCacheKeys.Any(k => GetPermissionNameFormCacheKeyOrNull(k) == x.Name)).ToList(); 

改为

var names = notCacheKeys.Select(k => GetPermissionNameFormCacheKeyOrNull(k)).ToArray(); 
 
var permissions = (await PermissionDefinitionManager.GetPermissionsAsync()) 
    .Where(x => names .Any(k => k == x.Name)).ToList(); 

速度从6秒到几秒? 6969ms到92ms

Answer

上面的问题,只解决了部分问题,我的程序是7.2.2 的微服务框架,没有升级到最新版本,但是会把一些高版本的优化,copy到本地重新发布dll替换原有的dll await Cache.SetManyAsync(cacheItems); 大量权限的时候设置缓存还是有2s,每次用户登录,获取Role ,User 权限都会有2s ,一起就是4s左右, 可能还要加OneTime方法,程序启动的时候把全部信息加载到缓存,后期用户登录才可能比较快。现在是第一次登录慢,第二次才快 系统启动热数据还是要加载到缓存

Answer

https://github.com/abpframework/abp/blob/dev/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs#L178-L179

var permissions = (await PermissionDefinitionManager.GetPermissionsAsync())
                .Where(x => notCacheKeys.Any(k => GetPermissionNameFormCacheKeyOrNull(k) == x.Name)).ToList();

改为

var names = notCacheKeys.Select(k => GetPermissionNameFormCacheKeyOrNull(k)).ToArray();

var permissions = (await PermissionDefinitionManager.GetPermissionsAsync())
    .Where(x => names .Any(k => k == x.Name)).ToList();
Answer

好像不是这个函数GetPermissionNameFormCacheKeyOrNull的问题

(await PermissionDefinitionManager.GetPermissionsAsync()).Where(x => notCacheKeys.Any(k => GetPermissionNameFormCacheKeyOrNull(k) == x.Name)).ToList()

notCacheKeys.Any(k => GetPermissionNameFormCacheKeyOrNull(k) == x.Name),每次都要全量转字符串匹配再Any, (await PermissionDefinitionManager.GetPermissionsAsync()). Count1 notCacheKeys Count2 O(Count1*Count2)

Answer

很多这样的权限 pn:R,pk:admin,n:C1:PQCManage.TestResultPqcSp.Update C1:PQCManage.TestResultPqcSp.Update 很多这种类型,C1:PQCManage.TestResultPqcSp.Update ,C2:PQCManage.TestResultPqcSp.Update,C3:PQCManage.TestResultPqcSp.Update

Answer

Blazor Server 白屏时间成15s-10s+,但是页面还是白屏明细

Answer

可以解决,方法比较简单 var notCacheKeysPermissionNames = notCacheKeys.Select(t=>t.Split(',').Last().Substring(2)).ToList(); 没有考虑其他特殊情况,但是很快 根据缓存权限格式 private const string CacheKeyFormat = "pn:{0},pk:{1},n:{2}"; 耗时从4989ms到96ms GetPermissionNameFormCacheKeyOrNull 这个函数的找个方法,需要特殊处理什么字符串么,有些函数没有使用过 var result = FormattedStringValueExtracter.Extract(cacheKey, CacheKeyFormat, true); FormattedStringValueExtracter这个类。 ` using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq;

namespace Volo.Abp.Text.Formatting;

///

/// This class is used to extract dynamic values from a formatted string. /// It works as reverse of /// public class FormattedStringValueExtracter { /// /// Extracts dynamic values from a formatted string. /// /// String including dynamic values /// Format of the string /// True, to search case-insensitive. public static ExtractionResult Extract(string str, string format, bool ignoreCase = false) { var stringComparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;

    if (str == format)
    {
        return new ExtractionResult(true);
    }

    var formatTokens = new FormatStringTokenizer().Tokenize(format);
    if (formatTokens.IsNullOrEmpty())
    {
        return new ExtractionResult(str == "");
    }

    var result = new ExtractionResult(true);

    for (var i = 0; i < formatTokens.Count; i++)
    {
        var currentToken = formatTokens[i];
        var previousToken = i > 0 ? formatTokens[i - 1] : null;

        if (currentToken.Type == FormatStringTokenType.ConstantText)
        {
            if (i == 0)
            {
                if (!str.StartsWith(currentToken.Text, stringComparison))
                {
                    result.IsMatch = false;
                    return result;
                }

                str = str.Substring(currentToken.Text.Length);
            }
            else
            {
                var matchIndex = str.IndexOf(currentToken.Text, stringComparison);
                if (matchIndex < 0)
                {
                    result.IsMatch = false;
                    return result;
                }

                Debug.Assert(previousToken != null, "previousToken can not be null since i > 0 here");

                result.Matches.Add(new NameValue(previousToken.Text, str.Substring(0, matchIndex)));
                str = str.Substring(matchIndex + currentToken.Text.Length);
            }
        }
    }

    var lastToken = formatTokens.Last();
    if (lastToken.Type == FormatStringTokenType.DynamicValue)
    {
        result.Matches.Add(new NameValue(lastToken.Text, str));
    }

    return result;
}

/// <summary>
/// Checks if given <paramref name="str"/> fits to given <paramref name="format"/>.
/// Also gets extracted values.
/// </summary>
/// <param name="str">String including dynamic values</param>
/// <param name="format">Format of the string</param>
/// <param name="values">Array of extracted values if matched</param>
/// <param name="ignoreCase">True, to search case-insensitive</param>
/// <returns>True, if matched.</returns>
public static bool IsMatch(string str, string format, out string[] values, bool ignoreCase = false)
{
    var result = Extract(str, format, ignoreCase);
    if (!result.IsMatch)
    {
        values = new string[0];
        return false;
    }

    values = result.Matches.Select(m => m.Value).ToArray();
    return true;
}

/// <summary>
/// Used as return value of <see cref="Extract"/> method.
/// </summary>
public class ExtractionResult
{
    /// <summary>
    /// Is fully matched.
    /// </summary>
    public bool IsMatch { get; set; }

    /// <summary>
    /// List of matched dynamic values.
    /// </summary>
    public List<NameValue> Matches { get; private set; }

    internal ExtractionResult(bool isMatch)
    {
        IsMatch = isMatch;
        Matches = new List<NameValue>();
    }
}

}

`

Answer

PermissionStore.GetPermissionNameFormCacheKeyOrNull 存在性能问题

Answer

跟查询数据库没关系了,主要是 pn:R,pk:admin,n:AbpIdentity.Roles ,转Name 匹配 var permissions = dbpermissions.Where(x => notCacheKeys.Any(k => GetPermissionNameFormCacheKeyOrNull(k) == x.Name)).ToList(); 也就是 没修改源码之前的 var permissions = (await PermissionDefinitionManager.GetPermissionsAsync()) .Where(x => notCacheKeys.Any(k => GetPermissionNameFormCacheKeyOrNull(k) == x.Name)).ToList();

Showing 1 to 10 of 55 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.0.0-preview. Updated on September 18, 2025, 07:10