当前位置:网站首页 / WPF / 正文

2020 WPF 取经之路第5天 - 分解 Markdig.SyntaxHighlighting ImmutableList

时间:2020年03月19日 | 作者 : aaronyang | 分类 : WPF | 浏览: 315次 | 评论 0

取经12 ResourceKey

这个和ComponentResourceKey

image.png

是父子类的关系

image.png

这里作者写了一个StyleResourceKey,估计是为了获得Key属性,估计还有可能区别 资源类型

private sealed class StyleResourceKey : ResourceKey
		{
			public StyleResourceKey(string key)
				=> Key = key;

			public override string ToString()
				=> "XamlStyle: " + Key;

			public override bool Equals(object obj)
				=> obj is StyleResourceKey srk ? Key.Equals(srk.Key) : base.Equals(obj);

			public override int GetHashCode()
				=> Assembly.GetHashCode() ^ Key.GetHashCode();

			public string Key { get; }
			public override Assembly Assembly => typeof(StyleResourceKey).Assembly;
		} // class StyleResourceKey


取经13  MethodImpl

MethodImpl(MethodImplOptions.AggressiveInlining)

AggressiveInlining:

此方法应内联(如果可能)。

ForwardRef:

此方法被声明,但提供该方法实现的在其他地方。

InternalCall:

内部调用是对在公共语言运行时内部实现的方法的调用。

NoInlining:

不能内联该方法。内联是用方法主体代替方法调用的优化。

NoOptimization:

调试可能的代码生成问题时优化该方法不是实时 (JIT) 编译器和本机代码生成(请参见 )。

PreserveSig:

此方法签名完全按声明的样子导出。

Synchronized:

该方法一次只能由一个线程执行。静态方法锁定类型,而实例方法锁定实例。在任何实例函数中只能执行一个线程,并且在类的任何静态函数中只能执行一个线程。

Unmanaged:

该方法以非托管代码实现。


测试线程

static void Main(string[] args)
        {
            Program p = new Program();
            for (int i = 0; i < 10; i++)
            {
                Thread t = new Thread(p.Execute);
                t.Start();
            }
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public void Execute()
        {
            Console.WriteLine("Excute at {0}", DateTime.Now);
            Thread.Sleep(2000);
        }

更多深入MethodImpl : 文章


接下来

image.png

这个项目是比较  Markdig.Wpf和作者的NeoMarkdigXaml的项目

看到一行内存释放代码

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);



项目地址:Markdig.SyntaxHighlighting

这个项目是个扩展项目,因为markdig在维护,所以会添加新的md节点,你需要加上对应的renderer,去解析



在迁移Neo项目时候,换成4.0后,发现

[MethodImpl(MethodImplOptions.AggressiveInlining)]  4.0的项目是没有的这个值的


取经15:使用GetRuntimeProperty方法  这是.net 4.5以上的

image.png

到底使用有啥区别呢

命名空间System.Reflection为利用Type对象提供了一些新的扩展方法.其中两个是GetRuntimeProperty(字符串名称)和GetRuntimeProperties().

image.png

ID返回null

番外文章: 地址

内部GetRuntimeProperty调用Type.GetProperty(name),它搜索具有指定名称的公共属性.属性ID受到保护,因此无法找到

public static PropertyInfo GetRuntimeProperty(this Type type, string name)
{
    CheckAndThrow(type);
    return type.GetProperty(name);
}

GetRuntimeProperties返回公共和非公共属性

public static IEnumerable<PropertyInfo> GetRuntimeProperties(this Type type)
{
    CheckAndThrow(type);
    return type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public |
                              BindingFlags.Static | BindingFlags.Instance);
}

GetRuntimeProperties的目的是返回IEnumerable< PropertyInfo>所有属性的集合,让您通过LINQ过滤该集合.您可以选择公共,非公共或任何其他类型的属性.使用GetRuntimeProperty返回的单个属性,您不需要这种灵活性,因此它受限于大多数常见用法


所以迁移项目,最终我换成4.5了,下载Markdig.SyntaxHighlighting 项目后

源码转移到该项目下,然后nuget一下 colorcode库

image.png

这个项目 主要针对CodeBlock这个renderer


新建一个插件拓展

using System;
using ColorCode;
using Markdig.Renderers;
using Markdig.Renderers.Html;

namespace Markdig.SyntaxHighlighting {
    public class SyntaxHighlightingExtension : IMarkdownExtension {
        private readonly IStyleSheet _customCss;

        public SyntaxHighlightingExtension(IStyleSheet customCss = null)
        {
            _customCss = customCss;
        }

        public void Setup(MarkdownPipelineBuilder pipeline) {}

        public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) {
            if (renderer == null) {
                throw new ArgumentNullException(nameof(renderer));
            }

            var htmlRenderer = renderer as TextRendererBase<HtmlRenderer>;
            if (htmlRenderer == null) {
                return;
            }

            var originalCodeBlockRenderer = htmlRenderer.ObjectRenderers.FindExact<CodeBlockRenderer>();
            if (originalCodeBlockRenderer != null) {
                htmlRenderer.ObjectRenderers.Remove(originalCodeBlockRenderer);
            }

            htmlRenderer.ObjectRenderers.AddIfNotAlready(
                new SyntaxHighlightingCodeBlockRenderer(originalCodeBlockRenderer, _customCss));
        }
    }
}
public static class SyntaxHighlightingExtensions {
        public static MarkdownPipelineBuilder UseSyntaxHighlighting(this MarkdownPipelineBuilder pipeline, IStyleSheet customCss = null) {
            pipeline.Extensions.Add(new SyntaxHighlightingExtension(customCss));
            return pipeline;
        }
    }

这个库暂时不看了,用不到



Markdig.Extensions.ScriptCs

这是Markdig的扩展,它允许C#脚本生成markdown或HTML内容。

相当于Markdown中可以写C#脚本

这个库 更牛班了。能力有限,我的目标是 写一个 md 笔记工具,类似有道云笔记


现在2个最好的思路,1个是生成xaml,但是代码着色这块工作量挺大的,第二个生成html,那么右侧是html,也是目前最好的选择。




取经16 ImmutableList集合

image.png

    public class Account

    {

        public string Name { get; set; }

        public decimal Amount { get; set; }

    }

使用ToImmutableList方法把list 转换为 不可改变的list集合

            List<Account> accounts = new List<Account>()
            {
                new Account{ Name = "July", Amount = 66889m},
                new Account{ Name = "Joyn", Amount = -120m},
                new Account{ Name = "John", Amount = 200m}
            };
            ImmutableList<Account> immutableAccounts = accounts.ToImmutableList();

添加测试

image.png

不可变的集合,效果出现了。

测试修改值

image.png

是同一个对象的。

但是集合被锁定总容量了,不可以修改


移除测试

image.png

原来的集合还是没有修改的。


那么如何移除呢?

    ImmutableList<Account>.Builder builder = immutableAccounts.ToBuilder();
            for (int i = 0; i < builder.Count; i++)
            {
                Account a = builder[i];
                if (a.Amount > 0)
                {
                    builder.Remove(a);
                }
            }

image.png

也就是说,两个集合 是2个容器,但是引用对象还是那个 引用的。


微软Core3.1 也内置了这个类型

https://docs.microsoft.com/en-us/dotnet/api/system.collections.immutable.immutablelist-1?view=netcore-3.1

image.png

很多哦

ImmutableArray<T>

ImmutableStack<T>

ImmutableQueue<T>

ImmutableList<T>

ImmutableHashSet<T>

ImmutableSortedSet<T>

ImmutableDictionary<K, V>

ImmutableSortedDictionary<K, V>



线程安全的集合测试

static void Main(string[] args)
        {
            // Construct a ConcurrentQueue.
            ConcurrentQueue<int> cq = new ConcurrentQueue<int>();
 
            // Populate the queue.
            for (int i = 0; i < 10000; i++) cq.Enqueue(i);
 
            // Peek at the first element.
            int result;
            if (!cq.TryPeek(out result))
            {
                Console.WriteLine("CQ: TryPeek failed when it should have succeeded");
            }
            else if (result != 0)
            {
                Console.WriteLine("CQ: Expected TryPeek result of 0, got {0}", result);
            }
 
            int outerSum = 0;
            // An action to consume the ConcurrentQueue.
            Action action = () =>
            {
                int localSum = 0;
                int localValue;
                while (cq.TryDequeue(out localValue)) localSum += localValue;
                Interlocked.Add(ref outerSum, localSum);
            };
 
            // Start 4 concurrent consuming actions.
            Parallel.Invoke(action, action, action, action);
 
            Console.WriteLine("outerSum = {0}, should be 49995000", outerSum);
        }



 AYUI       www.ayjs.net      AY         杨洋原创编写,请不要转载谢谢



推荐您阅读更多有关于“wpf share,”的文章

猜你喜欢

额 本文暂时没人评论 来添加一个吧

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

  查看权限

合肥科大智能常年招聘.NET,Web前端,有想换工作的私聊我AY唯一QQ:875556003和AY交流

抖音号:wpfui,可以看到我的很多作品效果,私活合作请qq联系我

AYUI8社区版Github地址:前往获取

作者:杨洋(AaronYang简称AY,安徽六安人)目前是个人,还没公司AY唯一QQ:875556003和AY交流

高中学历,2015年1月17日开始,兴趣学习研究WPF,目前工作繁忙,不接任何活

声明:AYUI7个人与商用免费,源码可购买。部分DEMO不免费.AY主要靠卖技术服务挣钱

不是从我处购买的ayui7源码,我不提供任何技术服务,如果你举报从哪里买的,我可以帮你转正为我的客户,并送demo

查看捐赠

AYUI7.X MVC教程 更新如下:

第一课 第二课 程序加密教程

vs2015 企业版密钥HM6NR-QXX7C-DFW2Y-8B82K-WTYJV

vs2017 企业版密钥NJVYC-BMHX2-G77MM-4XJMR-6Q8QF

标签列表