<<展现C#>> 第八章 用C#写组件(修订)

PyTorch模型生产部署:ONNX/Triton导出与高可用架构实战 机器学习模型部署本质是训练环境与生产环境之间的运行时契约建立过程,涉及序列化协议、推理引擎兼容性、动态批处理及资源隔离等核心问题。ONNX凭借标准化算子集和跨框架支持,成为平衡兼容性、性能与可维护性的首选导出格式;Triton Inference Server则通过原生多框架支持、动态batching和热加载能力,显著提升GPU利用率与服务SLA保障水平。在金融风控、电商推荐等高要求场景中,基于ONNX+Triton+K8s的分层架构可稳定支撑千级QPS与毫秒级P95延迟,同时满足模型热更新、可观测性与版本 阅读详情

第八章    用C#写组件

 

这一章关于用C#写组件。你学到如何写一个组件,如何编译它,且如何在一个客户程序中使用它。更深入一步是运用名字空间来组织你的应用程序。

这章由两个主要大节构成:

。你的第一个组件

。使用名字空间工作

 

8.1  你的第一个组件

到目前为止,在本书中提到的例子都是在同一个应用程序中直接使用一个类。类和它的使用者被包含在同一个执行文件中。现在我们将把类和使用者分离到组件和客户,它们分别位于不同的二进制文件中(可执行文件)。

尽管你仍然为组件创建一个 DLL,但其步骤与用C++写一个COM组件差别很大。你很少涉及到底层结构。以下小节说明了如何构建一个组件以及客户是如何使用它的:

 

。构建组件

。编译组件

。创建一个简单的客户应用程序

 

8.1.1  构建组件

     因为我是一个使用范例迷,我决定创建一个相关Web的类,以方便你们使用。它返回一个Web网页并储存在一个字符串变量中,以供后来重用。所有这些编写都参考了.NET Framwork的帮助文档。

类名为RequestWebPage;它有两个构造函数、一个属性和一个方法。属性被命名为URL,且它储存了网页的Web地址,由方法GetContent返回。这个方法为你做了所有的工作(见清单8.1)。

 

清单 8.1   用于从Web服务器返回HTML网页的RequestWebPage 类

 

 1: using System;

 2: using System.Net;

 3: using System.IO;

 4: using System.Text;

 5:

 6: public class RequestWebPage

 7: {

 8:  private const int BUFFER_SIZE = 128;

 9:  private string m_strURL;

10:

11:  public RequestWebPage()

12:  {

13:  }

14:

15:  public RequestWebPage(string strURL)

16:  {

17:   m_strURL = strURL;

18:  }

19:

20:  public string URL

21:  {

22:   get { return m_strURL; }

23:   set { m_strURL = value; }

24:  }

25:  public void GetContent(out string strContent)

26:  {

27:   // 检查 URL

28:   if (m_strURL == "")

29:    throw new ArgumentException("URL must be provided.");

30:

31:  WebRequest theRequest = (WebRequest) WebRequestFactory.Create(m_strURL);

32:   WebResponse theResponse = theRequest.GetResponse();

33:

34:   // 给回应设置字节缓冲区

35:   int BytesRead = 0;

36:   Byte[] Buffer = new Byte[BUFFER_SIZE];

37:

38:   Stream ResponseStream = theResponse.GetResponseStream();

39:   BytesRead = ResponseStream.Read(Buffer, 0, BUFFER_SIZE);

40:

41:   //使用 StringBuilder  以加速分配过程

42:   StringBuilder strResponse = new StringBuilder("");

43:   while (BytesRead != 0 )

44:   {

45:    strResponse.Append(Encoding.ASCII.GetString(Buffer,0,BytesRead));

46:    BytesRead = ResponseStream.Read(Buffer, 0, BUFFER_SIZE);

47:   }

48:

49:   // 赋给输出参数

50:   strContent = strResponse.ToString();

51:  }

52: }

 

本应该利用无参数构造函数完成工作,但我决定在构造函数中初始化URL,这可能会很有用。当后来决定要改变URL时——为了返回第二个网页,例如,通过URL属性的get和set访问标志使它被公开了。

有趣的事始于GetContent方法。首先,代码对URL实行十分简单的检查,如果它不适合,就会引发一个ArgumentException 异常。之后,我请求WebRequestFactory ,以创建一个基于传递给它的URL的WebRequest对象。

因为我不想发送cookies、附加头和询问串等,所以立即访问WebResponse(第32行)。如果你需要请求上述任何的功能,必须在这一行之前实现它们。

第35和36行初始化一个字节缓冲区,它用于从应答流(response stream)中读数据。暂时忽略StringBuilder 类,只要应答流中仍然有要读的数据,while循环就会简单地重复。最后的读操作将返回零,因此结束了该循环。

现在我想回到StringBuilder类。为什么用这个类的实例而不是简单地把字节缓冲区合并到一个字符串变量?看下面这个例子:

strMyString = strMyString + "some more text";

这里很清楚,你正在拷贝值。常量 "some more text" 以一个字符串变量类型被加框,且根据加法操作创建了一个新的字符串变量。接着被赋给了 strMyString。有很多次拷贝,是吗?

但你可能会争论

strMyString += "some more text";

不要炫耀这种行为。对不起,对于C#这是一个错误的答案。其运行完全与所描述的赋值操作相同。

不涉及该问题的另外的途径是使用StringBuilder类。它利用一个缓冲区进行工作,接着,在没有发生我所描述的拷贝行为的情况下,你进行追加、插入、删除和替换操作。这就是为什么我在类中使用它来合并那些读自缓冲区中的内容。

该缓冲区把我领进了这个类中最后重要的代码片段——第45行的编码转换。它只不过涉及到我获得请求的字符集。

最后,当所有的内容被读入且被转换时,我显式地从 StringBuilder请求一个字符串对象并把它赋给了输出变量。一个返回值仍然会导致另外的拷贝操作。

 

8.1.2  编译组件

到目前为止,你所做的工作与在正常应用程序的内部编写一个类没有什么区别。所不同的是编译过程。你必须创建一个库而不是一个应用程序:

csc /r:System.Net.dll /t:library /out:wrq.dll webrequest.cs

编译开关/t:library  告诉C#编译器,要创建一个库而不是搜寻一个静态 Main方法。同样,因为我正在使用 System.Net名字空间,所以必须引用 (/r:)它的库,这个库就是System.Net.dll。

你的库命名为 wrq.dll,现在它准备用于一个客户应用程序。因为在这章中我仅使用私有组件工作,所以你不必把库拷贝到一个特殊的位置,而是拷贝到客户应用程序目录。

 

8.1.3  创建一个简单的客户应用程序

当一个组件被写成且被成功地编译时,你所要做的就是在客户应用程序中使用它。我再次创建了一个简单的命令行应用程序,它返回了我维护的一个开发站点的首页(见清单8.2)。

 

清单 8.2    用 RequestWebPage 类返回一个简单的网页

 

 1: using System;

 2:

 3: class TestWebReq

 4: {

 5:  public static void Main()

 6:  {

 7:   RequestWebPage wrq = new RequestWebPage();

 8:   wrq.URL = "http://www.alphasierrapapa.com/iisdev/";

 9:

10:   string strResult;

11:   try

12:   {

13:    wrq.GetContent(out strResult);

14:   }

15:   catch (Exception e)

16:   {

17:    Console.WriteLine(e);

18:    return;

19:   }

20:

21:   Console.WriteLine(strResult);

22:  }

23: }

注意,我已经在一个try catch语句中包含了对 GetContent的调用。其中的一个原因是GetContent可能引发一个 ArgumentException异常。此外,我在组件内部调用的.NET Framwork类也可以引发异常。因为我不能在类的内部处理这些异常,所以我必须在这里处理它们。

其余的代码只不过是简单的组件使用——调用标准的构造函数,访问一个属性,并执行一个方法。但等一下:你需要注意何时编译应用程序。一定要告诉编译器,让它引用你的新组件库DLL:

csc /r:wrq.dll wrclient.cs

现在万事俱备,你可以测试程序了。输出结果会滚屏,而你可以看到应用程序工作。使用了常规的表达式,你也可以增加代码,以解析返回的HTML,并依据你个人的喜好,提取信息。我预想会使用到这个类新版本的SSL(安全套接字层),用于ASP+网页中的在线信用卡验证。

你可能会注意到,没有特殊的using 语句用于你所创建的库。原因是你在组件的源文件中没有定义名字空间。

 

8.2  使用名字空间工作

    你经常使用到名字空间,例如System 和System.Net。C#利用名字空间来组织程序,而且组织的层次结构特性使一个程序的元素传到另一个程序变得更容易。即使名字空间不用于外部描述,它们也是内部组织应用程序的好办法。

尽管不是强制的,但你总要创建名字空间,以清楚地识别应用程序的层次结构。.NET Framwork会给出构建这种层次结构的良好思想。

以下的代码片段显示了在C#原文件中简单的名字空间 My.Test(点号表示一个层次结构等级)的声明:

 

namespace My.Test

{

  //这里的任何东西属于名字空间

}

 

当你访问名字空间中的一个元素时,也有必要使用名字空间标识符全面地限定它,或者利用using标志把所有的成员引入到你当前的名字空间。本书前面的例子演示了如何应用这些技术。

在开始使用名字空间之前,只有少数有关存取安全的词。如果你不增加一个特定的存取修饰符,所有的类型将被默认为internal 。当你想从外部访问该类型时,使用 public 。不允许其它的修饰符。

这是关于名字空间充分的理论。让我们继续实现该理论——以下小节说明了当构建组件应用程序时,如何使用名字空间

。在名字空间中包装类

。在客户应用程序中使用名字空间

。为名字空间增加多个类

 

8.2.1  在名字空间中包装类

    既然你知道了名字空间的理论含义,那么让我们在现实生活中实现它吧。在这个以及即将讨论到的例子中,自然选择到的名字空间是Presenting.CSharp。为了不使你厌烦,仅仅是把RequestWebPage包装到Presenting.CSharp中,我决定写一个类,用于 Whois查找(见清单8.3)。

 

清单 8.3   在名字空间中实现 WhoisLookup类

 

 1: using System;

 2: using System.Net.Sockets;

 3: using System.IO;

 4: using System.Text;

 5:

 6: namespace Presenting.CSharp

 7: {

 8: public class WhoisLookup

 9: {

10:  public static bool Query(string strDomain, out string strWhoisInfo)

11:  {

12:   const int BUFFER_SIZE = 128;

13:

14:   if ("" == strDomain)

15:    throw new ArgumentException("You must specify a domain name.");

16:

17:   TCPClient tcpc = new TCPClient();

18:   strWhoisInfo = "N/A";

19:

20:   // 企图连接 whois  服务器

21:   if (tcpc.Connect("whois.networksolutions.com", 43) != 0)

22:     return false;

23:        

24:   // 获取流

25:   Stream s = tcpc.GetStream();

26:

27:   // 发送请求

28:   strDomain += "/r/n";

29:   Byte[] bDomArr = Encoding.ASCII.GetBytes(strDomain.ToCharArray());

30:   s.Write(bDomArr, 0, strDomain.Length);  

31:     

32:   Byte[] Buffer = new Byte[BUFFER_SIZE];

33:   StringBuilder strWhoisResponse = new StringBuilder("");

34:

35:   int BytesRead = s.Read(Buffer, 0, BUFFER_SIZE);

36:   while (BytesRead != 0 )

37:   {

38:   strWhoisResponse.Append(Encoding.ASCII.GetString(Buffer,0,BytesRead));

39:   BytesRead = s.Read(Buffer, 0, BUFFER_SIZE);

40:   }

41:

42:   tcpc.Close();

43:   strWhoisInfo = strWhoisResponse.ToString();

44:   return true;

45:  }

46: }

47: }

 

名字空间在第6行被声明,而且它用第7行和第47行的花括弧括住了WhoisLookup类。要声明自己新的名字空间,实际要做的就是这些。

在WhoisLookup类中当然具有一些有趣代码,特别它说明了使用C#进行socket编程易如反掌。在static Query 方法中经过“非空”的域名检查之后,我实例化了TCPClient类型的一个对象,它用来完成 Whois服务器所占用的43端口上的所有通讯。在第21行建立了服务器连接:

if (tcpc.Connect("whois.networksolutions.com", 43) != 0)

因为连接失败是预料到的结果,所以这个方法不能引发一个异常。(你还记住异常处理的“要”和“不要”吗?) 返回非零值是一个错误代码,而返回零则说明连接成功。

对于 Whois 查找,我必须首先发出一些信息给服务器——我要查找的域名。要完成此项工作,首先获取一个引用到当前TCP连接的双向流(第25行)。接着在域名后附加上一个回车/换行对,以表示查询结束。重新以字节数组打包,向Whois 服务器发送一个请求(第30行)。

余下的代码和RequestWebPage类极其相似。在该类中,我再次利用一个缓冲区从远程服务器读入应答。当缓冲区完成读入后,连接被断开。返回的应答被转给了调用者。我显式地调用 Close 方法的原因是我不想等待垃圾收集器毁坏连接。连接时间不要过长,以免占用TCP端口这种稀有资源。

在可以使用.NET 组件中的类之前,你必须把它作为一个库来编译。尽管现在有了一个已定义的名字空间,该编译命令仍然没有变:

csc /r:System.Net.dll /t:library /out:whois.dll whois.cs

注意,如果你想该库按与C#源文件相同的方法命名,就没有必要规定 /out:开关。规定该开关是一个良好的习惯,因为很多项目不会只由单个源文件组成。如果你规定了多个源文件,该库以名单中的第一个命名。

8.2.2  在客户应用程序中使用名字空间

由于你使用了名字空间开发组件,所以客户也要引入名字空间

using Presenting.CSharp;

或者给名字空间中的成员使用完全限定名(fully qualified name),例如

Presenting.CSharp.WhoisLookup.Query(...);

如果你不期望在名字空间中引入的元素之间出现冲突,using  标志( directive)是首选,特别是由于你具有很少的类型时。使用组件的客户程序样本在清单8.4中给出。

 

清单  8.4  测试 WhoisLookup 组件

 

 1: using System;

 2: using Presenting.CSharp;

 3:

 4: class TestWhois

 5: {

 6:  public static void Main()

 7:  {

 8:   string strResult;

 9:   bool bReturnValue;

10:

11:   try

12:   {

13:    bReturnValue = WhoisLookup.Query("microsoft.com", out strResult);

14:   }

15:   catch (Exception e)

16:   {

17:    Console.WriteLine(e);

18:    return;

19:   }

20:   if (bReturnValue)

21:    Console.WriteLine(strResult);

22:   else

23:    Console.WriteLine("Could not obtain information from server.");

24:  }

25: }

 

第2行利用using 标志引入了Presenting.CSharp名字空间。现在,我无论什么时候引用WhoisLookup ,都可以忽略名字空间的完全限定名了。

该程序对 microsoft.com 域进行一次Whois 查找——你也可以用自己的域名代替microsoft.com 。允许命令行参数传递域名,可使客户的用途更广。清单8.5 实现了该功能,但它不能实现适当的异常处理(为了使程序更短)。

 

清单  8.5  传递命令行参数给Query 方法

 

 1: using System;

 2: using Presenting.CSharp;

 3:

 4: class WhoisShort

 5: {

 6:  public static void Main(string[] args)

 7:  {

 8:   string strResult;

 9:   bool bReturnValue;

10:

11:   bReturnValue = WhoisLookup.Query(args[0], out strResult);

12:

13:   if (bReturnValue)

14:    Console.WriteLine(strResult);

15:   else

16:    Console.WriteLine("Lookup failed.");

17:  }

18: }

 

你所必须做的就是编译这个应用程序:

csc /r:whois.dll whoisclnt.cs

接着可以使用命令行参数执行该应用程序。例如,以 microsoft.com参数执行

whoisclnt microsoft.com

当查询运行成功时,就会出现 microsoft.com的注册信息。(清单8.6 显示了输出的简略版本)  这是一个很方便的小程序,通过组件化的途径写成的,花不到一个小时。如果用C++编写,要花多长时间?很幸运,我再也想不起当第一次用C++这样做时,花了多长的时间。

 

清单 8.6   有关 microsoft.com (简略) 的Whois 信息

D:/CSharp/Samples/Namespace>whoisclient

...

 

Registrant:

Microsoft Corporation (MICROSOFT-DOM)

  1 microsoft way

  redmond, WA 98052

  US

  Domain Name: MICROSOFT.COM

 

  Administrative Contact:

   Microsoft Hostmaster (MH37-ORG) msnhst@MICROSOFT.COM

  Technical Contact, Zone Contact:

   MSN NOC (MN5-ORG) msnnoc@MICROSOFT.COM

  Billing Contact:

   Microsoft-Internic Billing Issues (MDB-ORG)     msnbill@MICROSOFT.COM

 

  Record last updated on 20-May-2000.

  Record expires on 03-May-2010.

  Record created on 02-May-1991.

  Database last updated on 9-Jun-2000 13:50:52 EDT.

 

  Domain servers in listed order:

 

  ATBD.MICROSOFT.COM      131.107.1.7

  DNS1.MICROSOFT.COM      131.107.1.240

  DNS4.CP.MSFT.NET       207.46.138.11

  DNS5.CP.MSFT.NET       207.46.138.12

 

8.2.3  增加多个类到名字空间

使WhoisLookup和RequestWebPage 类共存于同一个名字空间是多么的美妙。既然WhoisLookup已是名字空间的一部分,所以你只须使RequestWebPage 类也成为该名字空间的一部分。

必要的改变很容易被应用。你只需使用名字空间封装RequestWebPage 类就可以了:

 

namespace Presenting.CSharp

{

public class RequestWebPage

{

...

}

}

 

尽管两个类包含于两个不同的文件,但在编译后,它们都是相同名字空间的一部分:

csc /r:System.Net.dll /t:library /out:presenting.csharp.dll whois.cs webrequest.cs

 

你不必按照名字空间的名字给DLL命名。然而,这样做会有助你更容易你记住,当编译一个客户应用程序时要引用哪一个库。

 

8.3  小结

    在这一章中,你学到了如何构建一个可以在客户程序中使用的组件。最初,你不必关心名字空间,但后面第二个组件中介绍了该特性。名字空间在内外部均是组织应用程序极佳的办法。

    C#中的组件很容易被创建,而且只要库和应用程序共存于相同的目录,你甚至不必进行特殊的安装。当要创建必须被多个客户使用的类库时,步骤就有所改变——而下一章将会告诉你为什么。

基于YOLOv8的表面裂痕等缺陷检测:深度学习与UI界面的实践 本文详细介绍了如何使用YOLOv8进行表面裂痕等缺陷检测,并结合图形用户界面展示检测结果。通过YOLOv8的强大能力,我们可以实现高效、准确的表面缺陷检测,提升工业产品的质量控制水平。未来,随着深度学习技术和数据集的不断发展,表面缺陷检测的精度和速度将不断提升,应用领域也将进一步拓展。希望本文的实践能够为深度学习在工业检测领域的应用提供一些启示。 阅读详情

相关推荐

Gitlab+Jenkins+Docker+Harbor+K8s+Rancher集群搭建CICD平台

本文以诺依项目为例详细记录了Kubernetes集群的部署过程以及配套DevOps环境的搭建。主要内容包括:1) 配置8个节点的软硬件环境;2) 基础环境准备(网络、防火墙、Docker等);3) 三节点Kubernetes集群部署;4) GitLab代码仓库安装;5) Harbor私有镜像仓库搭建;6) Jenkins持续集成工具配置;7) 基于若依项目的CI/CD实践;8) Rancher集群管理工具部署。

hickman2023的博客 1201

Micro Framework WireProtocol协议介绍

【叶帆工作室】2009-2-151、简介WireProtocol协议是上位机MFDeploy或VS2008程序在诊断、部署、调试.Net Micro Framework设备及相关应用程序时的通信协议。该协议与具体的硬件链路无关,目前支持的物理连接有串口、网口、USB等。该协议为点对点协议,协议中没有设备地址的概念,在同一时间同一物理通道仅能调试一台设备。协议格式分两部分,帧头和负荷(P

刘洪峰AIoT | 一叶启帆·万物智联 9388

Jacobi正交多项式在数值分析中的应用与实现

本文深入探讨了Jacobi正交多项式在数值分析中的核心应用与实现。作为最通用的正交多项式族,Jacobi多项式通过参数α和β的调节,可退化为切比雪夫、勒让德等经典多项式,为函数逼近、奇异积分和微分方程求解提供了统一框架。文章重点解析了其在加权高斯积分(高斯-雅可比积分)和谱方法求解微分方程中的关键作用,并提供了基于递归关系和SciPy的稳定高效实现方案,帮助读者掌握这一强大的数值计算工具。

weixin_29306011的博客 245

《Human Listening and Live Captioning:Multi-Task Training for Speech Enhancement》

本篇文章的作者是Sefifik Emre Eskimez*, Xiaofei Wang*, Min Tang, Hemin Yang, Zirun Zhu,Zhuo Chen, Huaming Wang, Takuya Yoshioka,Microsoft, One Microsoft Way, Redmond, WA, USA 。 本篇文章主要是应用多任务实现听觉和现场字幕的应用,用了增强模型提高下游任务ASR模型的性能。 研究动机 网上会议、疫情等原因使得人们在网上办公的概率变大,如何能够使得办公

qq_46079584的博客 534

论文阅读——Bayesian Knowledge Fusion(贝叶斯知识融合)

该篇论文解决了不确定环境中的信息融合问题。想象一下,有多位专家针对同一情况构建概率模型,我们希望汇总他们提供的信息。直接合并每个信息可能会遇到几个问题。例如,专家们可能不同意某个事件发生的概率,或者他们可能不同意两个事件之间因果关系的方向(例如,一个人认为 A 导致 B,而另一个人认为 B 导致 A)。他们甚至可能不同意概率网络中一组变量之间的整个依赖结构。

qq_64164071的博客 1497

海康工业相机使用:常见问题及解决方法

工业相机在使用过程中,经常会因为操作不当、使用环境不当等原因出现一些问题,本篇教程,主要针对海康工业相机常见问题及其定位方法做以简单介绍,希望可以帮助大家。 注:该教程对其他品牌工业相机“常见问题”排查,也具备一定的指导意义。 当出现无法通过客户端发现设备或者无法预览图像等问题,先确认当前的运行环境是否满足以下要求: 确认装有相机驱动软件的电脑网卡为千兆网卡(Gige接口相机); 确认网卡是否已开启巨型帧; 确认电脑与网口相机之间的网络链路为千兆; 确认装有相机驱动软件的USB接口为3...

Cche的博客 3万+

Composite UI Application Block(Cab)实例学习资料收集

1.1. Commands1.1.1.    类关系图图 2‑6 主要类关系图说明:1.         Command定义了一个命令,如“FileExit”,它跟一系列的CommandAdapter相关,好比一个命令可以从多个地方下发(菜单或工具栏等等)。2.         Command持有一个ICommandAdapterMapService接口,也正是这个接口,通

牛牛工作室 9634

RV1126开发板性能实测:网络、温度与功耗全解析

本文对RV1126开发板进行了全面的性能实测,重点分析了网络性能、温度表现与功耗特性。测试发现UDP带宽可达500Mbps,但TCP性能受限于协议栈;散热设计对持续性能至关重要,大板子在AI推理和视频推流中表现更稳定。为嵌入式开发者提供了真实的选型参考和优化建议。

d3e4f的博客 266

agentic-awesome-skills 中的 Azure Maps (.NET) 技能:位置服务 SDK 完整集成指南

本指南围绕 agentic-awesome-skills 仓库中的 `azure-maps-search-dotnet` 技能展开,系统讲解 Azure Maps SDK for .NET 的安装、认证、五大客户端(搜索、路由、渲染、地理定位、天气)以及 11 个核心工作流的实战用法。读完本文,你将掌握从地址地理编码、路径规划、地图瓦片到 IP 定位、天气查询的完整开发链路,并了解该技能在 AAS

gitblog_00017的博客 556

同花顺CM函数深度解析:如何精准设置历史换手衰减系数以优化筹码峰

本文深度解析同花顺CM函数中的历史换手衰减系数,揭示其如何影响筹码峰准确性。通过拆解CM函数参数,并提供基于前十大流通股东锁定比例的计算公式,指导用户精准设置该系数,从而优化筹码峰模型,使其更真实反映个股持仓成本分布,提升技术分析的有效性。

mango的博客 1779

oh-my-zsh详细安装与主题插件配置

使用Linux的小伙伴都知道默认shell是bash,但是对于喜欢折腾,喜欢酷炫的我们bash怎能够用。zsh的作为一种shell,功能更强大,但是配置复杂。后来,有大佬创建了一个名为oh-my-zsh的开源项目,使用方便,功能强大。 下面就去oh-my-zsh的配置。 ①安装zsh 想要安装oh-my-zsh,首先得安装zsh,输入命令 sudo apt-get install zsh 界面如下 ②查看是否安装成功 输入命令 zsh --version 可以查看安装zsh的版本..

惜洛-Jankin的博客 2万+

运用 Range 对象处理 Word 文档内容

在所有 Office 应用程序中,Microsoft Word 可能是应用最广泛的应用程序,它还经常在自定义 Office 解决方案中扮演重要的角色。开发人员用各种不同的方式使用 Word,有一些方式很简单,而另一些极其复杂。无论涉及何种自定义解决方案,用 Visual Basic for Applications (VBA) 处理 Word 文档的基本方法都是一样的。下边,我将概括地介绍如何使用...

weixin_34233679的博客 655

Opencv计算机视觉PPT-算法篇

01 02 03 04 05 06 07 08 09 010 011 012 013 014 015 016 017 018

Qt历险记,专注Qt技术,三年医疗设备研发经验,1年机器视觉研发经验,半年柔性传感研发经验。 204

<<展现C#>> 前言(补充) 和第三章 第一个C#程序(修订)

 前言0.1  提要    欢迎阅读《展现 C#》(Presenting C#)。这本书是你提高企业编程语言的一条捷径。这种企业编程语言带有下一代编程语言服务运行时(NGWS Runtime):C#(发音"C sharp")。    NGWS Runtime 是一个不仅管理执行代码、同时也提供使编程更加容易的动态环境。编译器产生受管代码以指向这种受管理执行环境。你获得跨平台语言集成、跨平台语言

rainbow的专栏 1465

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

经典技术书籍分享(4):《CLR Via C#》第三版 新增内容(Jeffrey Richter博文翻译)

Posted on 2010-06-06 20:32 Frank Xu Lei 阅读(395) 评论(6)  编辑收藏 所属分类: 经典技术书籍分享<br />Jeffrey Richter《CLR Via C#》第三版已经于2010年2月出版,关于这本书的下载地址,可以参考之前的文章。里面有英文版的介绍信息以及下载链接:经典技术书籍分享(3):《CLR Via C#》 3 目录和下载。这本书最明显的部分就是增加了第5部分:线程。<br />独立的5章内容。另外就是对于.NET3.0、4.0都做

微软特邀讲师 老徐FrankXuLei 的专栏 2699

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

《Microsoft .NET框架程序设计(修订版)》 第八章

第八章 常数与字段 Ø 8.1 常数 常数总被认为是类型的一部分。 Ø 8.2 字段 字段是以动态内存的形式存储的,因此只能在运行时刻获取它们的值。 只读字段只能在构造器内被赋值(定义时赋值实际上也就是在构造器内赋值),在构造器内只读字段可以被多次赋值。 很多字段都是以内联的方式进行初始化的(这里内联的意思即为在声明字段的同时进行初始化赋值)。C#允许我们采用这种方便的内联初始...

javatome 151

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

.NET框架程序设计(修订版)-- 笔记(三)

第Ⅲ部分 类型设计 第七章 类型成员及其访问限定 7.1类型成员 ①常数;②字段;③实例构造器;④类型构造器;⑤方法;⑥重载操作符;⑦转换操作符;⑧属性;⑨事件;⑩类型; 7.2访问限定修饰符和预定义特性P.173表7.1 ①private;②protected;③Internal;④protected internal;⑤public; 7.2.1类型预定义特性P.174表7....

linuxstuding 159

“C++ 之父交谈录“

既要高效用硬件、又要管理复杂度的那些应用。你如果只是想写脚本、做网页、快速原型,有更好的语言,别用 C++。但你如果写的东西将来会跑十年、会进车、进手机、进交易系统、进火星车——那这门语言被几亿人抱怨的那点"复杂",恰恰是它还能在四十年后继续演化的原因。“世界上只有两种语言:被人抱怨的,和没人用的。

linx295的博客 655

给了地图的数据接口地址如何拼url字段_用于 Power BI 地图可视化效果的提示和技巧...

Power BI 与必应地图集成,提供默认地图坐标(一种称为“地理位置编码”的过程),以便用户可以创建地图。 集成后,它们使用算法共同确定正确的位置,但有时只是一种最佳猜测。 如果 Power BI 进行了尝试,但无法自行创建地图可视化效果,则会借助必应地图的帮助。你或管理员可能需要更新防火墙,以允许访问必应用来地理编码的 URL。 这些 URL 是:https://dev.virtualeart...

weixin_39701735的博客 501

MICROSOFT HYPER-V SERVER 2019 许可协议

重要声明(后跟许可条款) 诊断和使用信息。微软会通过 Internet 自动收集可能与贵组织关联的信息,并使用此信息帮助改进您的安装、升级和用户体验,以及微软产品和服务的质量和安全性。Windows Hyper-V Server 具有四 (4) 个信息收集设置(安全、基础、增强和完整),并默认使用“增强”设置。增强级别包含执行以下任务所需的信息:(i) 运行我们的防恶意软件以及诊断和使用信息技术...

allway2的博客 2676

2021-01-22 AAAI-21 海报展示时间表 Main/AISI/SMT Track Poster Presentation Schedule

Dear AAAI-21 Main Track, AI for Social Impact Track, and Senior Member Track Authors, The final poster presentation schedule has now been finalized by the AAAI-21 program chairs and workflow chairs. As you can imagine, this has been a monumental and very.

计算机视觉 833

BingMapsRESTToolkit 项目常见问题解决方案

BingMapsRESTToolkit 项目常见问题解决方案 项目基础介绍 BingMapsRESTToolkit 是一个由微软开发的便携式 .NET 类库,旨在简化从 .NET 应用程序访问 Bing Maps REST 服务的过程。该项目的主要编程语言是 C#,适用于 .NET 平台。Bing Maps REST 服务提供了多种功能,包括自动建议、地理编码、路线计算、距离矩阵、等时线、道路匹配...

gitblog_00132的博客 801

C# Winform使用ListVIew控件制作表格

1、找到ListVIew拖到窗体中 2、点击右上角,设置视图为 Details,或者直接在属性里面设置View为Details 3、添加列表头:点击属性Columns 完后效果如下: 4、添加行表头:点击属性Items 5、添加行数据 注意: 在插入行输入的时候如果没有添加行的items会报一下错误: System.ArgumentOutOf...

LoveWeeknd 3万+

C#创建表格

1.新建Form窗体frmTest2.在工具箱中找到GridControl,拖入Form窗体3.点击Run Designer,然后在Columns项中可以添加字段,然后修改Name、Caption、FieldName值,其中Caption是表格显示的字段名,FildName是数据库字段名,可以参考如下: Name   id Caption id FieldName id Visabl...

abcwanglinyong的博客 3万+

C#自定义控件实现窗体绘制表格

C#自定义控件

IN 2万+
上一篇: <<展现C#>> 第七章 异常处理(修订)
下一篇: <<展现C#>> 第九章 配置和部署
rainbow
博客等级 码龄27年 3粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值