最新文章專題視頻專題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

開(kāi)源跨平臺(tái)運(yùn)行服務(wù)插件TaskCore.MainForm

來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 22:35:33
文檔

開(kāi)源跨平臺(tái)運(yùn)行服務(wù)插件TaskCore.MainForm

開(kāi)源跨平臺(tái)運(yùn)行服務(wù)插件TaskCore.MainForm:本次將要很大家分享的是一個(gè)跨平臺(tái)運(yùn)行的服務(wù)插件 - TaskCore.MainForm,此框架是使用.netcore來(lái)寫(xiě)的,現(xiàn)在netcore已經(jīng)支持很多系統(tǒng)平臺(tái)運(yùn)行了,所以將以前的Task.MainForm改良成跨平臺(tái)的服務(wù)共大家使用和相互交流;本來(lái)這篇應(yīng)該分享的是nginx+iis+
推薦度:
導(dǎo)讀開(kāi)源跨平臺(tái)運(yùn)行服務(wù)插件TaskCore.MainForm:本次將要很大家分享的是一個(gè)跨平臺(tái)運(yùn)行的服務(wù)插件 - TaskCore.MainForm,此框架是使用.netcore來(lái)寫(xiě)的,現(xiàn)在netcore已經(jīng)支持很多系統(tǒng)平臺(tái)運(yùn)行了,所以將以前的Task.MainForm改良成跨平臺(tái)的服務(wù)共大家使用和相互交流;本來(lái)這篇應(yīng)該分享的是nginx+iis+

本次將要很大家分享的是一個(gè)跨平臺(tái)運(yùn)行的服務(wù)插件 - TaskCore.MainForm,此框架是使用.netcore來(lái)寫(xiě)的,現(xiàn)在netcore已經(jīng)支持很多系統(tǒng)平臺(tái)運(yùn)行了,所以將以前的Task.MainForm改良成跨平臺(tái)的服務(wù)共大家使用和相互交流;本來(lái)這篇應(yīng)該分享的是nginx+iis+redis+Task.MainForm構(gòu)建分布式架構(gòu)后續(xù)文章,但使用.netcore來(lái)定義一個(gè)服務(wù)插件和跨平臺(tái)測(cè)試經(jīng)過(guò)讓我既興奮又頭痛,不說(shuō)了下次再分享分布式后續(xù)文章吧;那么開(kāi)始今天的分享內(nèi)容,希望各位多多支持:

. 框架結(jié)構(gòu)介紹及運(yùn)行效果圖

. 如何生成nuget包和使用開(kāi)源框架TaskCore.MainForm

. win7和ubuntu16.04運(yùn)行TaskCore.MainForm的兩種方式和測(cè)試截圖(也可認(rèn)為.netcore項(xiàng)目在win7和ubuntu系統(tǒng)運(yùn)行的兩種方式)

. 框架代碼解讀及感悟

下面一步一個(gè)腳印的來(lái)分享:

. 框架結(jié)構(gòu)介紹及運(yùn)行效果圖

首先,咋們先來(lái)認(rèn)識(shí)下項(xiàng)目源碼的工程目錄結(jié)構(gòu)如圖:

結(jié)構(gòu)看上去應(yīng)該夠清晰了,源碼文件量也很少,不過(guò)的確實(shí)現(xiàn)了動(dòng)態(tài)加載程序集dll來(lái)執(zhí)行任務(wù),后面會(huì)給出相應(yīng)的執(zhí)行截圖,我們?cè)賮?lái)看下TaskCore.MainForm項(xiàng)目通過(guò)vs2015生成之后Bin文件夾中的文件如圖:

如果安裝了.netcore sdk的話在windows上您只需要上面截圖的文件就能運(yùn)行插件了;再來(lái)我們?cè)谝呀?jīng)安裝過(guò)core sdk的win7系統(tǒng)上執(zhí)行一下如下命令dotnet TaskCore.MainForm.dll就能看到如圖的效果:

沒(méi)錯(cuò)這就是插件運(yùn)行起來(lái)的效果圖,因?yàn)?netcore現(xiàn)目前暫時(shí)沒(méi)有提供類似于winform那樣的皮膚界面效果,所有只能通過(guò)命令行來(lái)做跨平臺(tái)運(yùn)行程序

. 如何生成nuget包和使用TaskCore.MainForm

首先,我們要明確服務(wù)是由兩部分構(gòu)成(TaskCore.MainForm和TaskCore.Plugin);TaskCore.MainForm主要用來(lái)運(yùn)行程序,TaskCore.Plugin用來(lái)作為子任務(wù)需要繼承的父類插件;當(dāng)我們下載TaskCore.MainForm運(yùn)行包之后(如圖2結(jié)構(gòu)),我們還需要做的就是繼承TaskCore.Plugin.dl中的TPlugin這個(gè)類,來(lái)重寫(xiě)自己的任務(wù)內(nèi)容,因此我們新建一個(gè)項(xiàng)目取名為:TaskCore.Test,再來(lái)我們通過(guò)vs2015引用功能直接添加TaskCore.MainForm運(yùn)行包中的TaskCore.Plugin.dl引用,這個(gè)時(shí)候會(huì)提示一個(gè)錯(cuò)誤:

錯(cuò)誤意思是沒(méi)法加載netcore版本的dll,因此這種直接在vs項(xiàng)目中引用方式添加dll依賴不行,需要通過(guò)nuget來(lái)添加依賴包(.netcore對(duì)類庫(kù)的引用目前只能通過(guò)nuget來(lái)安裝依賴,這個(gè)需要注意),所以我這里把TaskCore.Plugin項(xiàng)目通過(guò)dotnet pack命令來(lái)生成nuget包,然后以便我TaskCore.Test項(xiàng)目中來(lái)使用;

如何生成nuget包(win7系統(tǒng)dotnet命令來(lái)生成包的過(guò)程和下載):

直接在vs中右鍵您需要打包的類庫(kù)項(xiàng)目-》選擇"在資源管理器中打開(kāi)文件夾"-》這樣就到了您類庫(kù)的根目錄,然后退到類庫(kù)根目錄的上一級(jí)文件夾中-》按住鍵盤”shift"鍵并同時(shí)鼠標(biāo)右鍵要打包類庫(kù)的項(xiàng)目文件件(我這里是TaskCore.Plugin文件夾)-》選擇“在此處打開(kāi)命令窗體” 這個(gè)時(shí)候就進(jìn)入了cmd命令窗體,當(dāng)然有些朋友直接喜歡直接先cmd再來(lái)找對(duì)應(yīng)的磁盤,反正我覺(jué)得第一種更快點(diǎn)(不同人不同選擇吧),下面看下操作截圖:

由上圖可以看到,通過(guò)命令生成了nupkg文件,這文件就是咋們需要在項(xiàng)目中下載安裝的TaskCore.Plugin插件包;接下來(lái)我們來(lái)在TaskCore.Test項(xiàng)目中安裝這個(gè)插件如下步奏,右鍵TaskCore.Plugin項(xiàng)目中的“引用”-》選擇“管理nuget程序包”-》然后選擇右上角的這個(gè)圖標(biāo)

-》選擇“Nuget包管理器”-》“程序包源”-》

-》然后選擇新創(chuàng)建的包源,下面設(shè)置如圖

這里的“源(S)”指定的本地路徑就是剛才我們生成的nupkg文件文件的磁盤(當(dāng)然我這里是吧剛才pack命令生成的文件復(fù)制到了MyNugPackage文件夾中方便測(cè)試)-》然后點(diǎn)擊”確定“按鈕-》然后在返回到

選擇我們的包源MyNugPackage-》再瀏覽這里就能看到我們創(chuàng)建的nuget包了

-》選擇并安裝-》好安裝好后我們可以查看“引用”下面有了如下變化

并且project.json文件中自動(dòng)添加了依賴項(xiàng):

好了到我們的TaskCore.Test項(xiàng)目中就可以使用Task.Plugin包里面的方法很類等信息了;

使用TaskCore.MainForm:

由上面的操作TaskCore.Test項(xiàng)目已經(jīng)安裝了Task.Plugin包,那么我們?cè)陧?xiàng)目中分別創(chuàng)建3個(gè)子類并繼承自Task.Plugin包的父類TPlugin并重寫(xiě)方法TPlugin_Load(),對(duì)應(yīng)文件名稱分別為:BlogsObj.cs,BlogsObj01.cs,BlogsObj02.cs,分別添加入下代碼內(nèi)容:

BlogsObj.cs:

namespace TaskCore.Test
{
 // This project can output the Class library as a NuGet Package.
 // To enable this option, right-click on the project and select the Properties menu item. In the Build tab select "Produce outputs on build".
 public class BlogsObj : TPlugin
 {
 public BlogsObj()
 {

 }

 public override void TPlugin_Load()
 {
 var sbLog = new StringBuilder(string.Empty);
 try
 {
 sbLog.Append($"這里是BlogsObj,獲取配置文件:{this.XmlConfig.Name}");

 //代碼塊
 //

 new WriteLog()._WriteLog($"{DateTime.Now}測(cè)試引用nuget包");

 }
 catch (Exception ex)
 {
 sbLog.Append($"異常信息:{ex.Message}");
 }
 finally
 {

 PublicClass._WriteLog(sbLog.ToString(), this.XmlConfig.Name);
 }
 }
 }
}

BlogsObj01.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TaskCore.Plugin;

namespace TaskCore.Test
{
 // This project can output the Class library as a NuGet Package.
 // To enable this option, right-click on the project and select the Properties menu item. In the Build tab select "Produce outputs on build".
 public class BlogsObj01 : TPlugin
 {
 public BlogsObj01()
 {

 }

 public override void TPlugin_Load()
 {
 var sbLog = new StringBuilder(string.Empty);
 try
 {
 sbLog.Append($"這里是BlogsObj01,獲取配置文件:{this.XmlConfig.Name}");

 //代碼塊
 //
 }
 catch (Exception ex)
 {
 sbLog.Append($"異常信息:{ex.Message}");
 }
 finally
 {
 //Console.WriteLine($"這里是Blogs,獲取配置文件:{this.XmlConfig.Name}");
 PublicClass._WriteLog(sbLog.ToString(), this.XmlConfig.Name);
 }
 }
 }
}

BlogsObj02.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TaskCore.Plugin;

namespace TaskCore.Test
{
 // This project can output the Class library as a NuGet Package.
 // To enable this option, right-click on the project and select the Properties menu item. In the Build tab select "Produce outputs on build".
 public class BlogsObj02 : TPlugin
 {
 public BlogsObj02()
 {

 }

 public override void TPlugin_Load()
 {
 //Console.WriteLine($"這里是Blogs,獲取配置文件:{this.XmlConfig.Name}");
 PublicClass._WriteLog($"這里是BlogsObj02,獲取配置文件:{this.XmlConfig.Name}", this.XmlConfig.Name);
 }
 }
}

好了測(cè)試代碼寫(xiě)完,咋們生成一下,然后把這個(gè)TaskCore.Test.dll拷貝到TaskCore.MainForm運(yùn)行包中,還需要在PluginXml文件夾中分別創(chuàng)建繼承TPlugin的子類的配置文件對(duì)應(yīng)的截圖如(注:這里xml配置文件名稱必須和子類名稱一樣):

配置文件內(nèi)容如BlogsObj.xml:

<!--
 1.xml配置模板
 2.utf-8文件
 3.復(fù)制到程序根目錄下面PluginXml文件夾下
 4.每個(gè)任務(wù)建議創(chuàng)建和程序dll名稱相同xml配置文件
-->
<TaskMain>
 <!--固定:執(zhí)行任務(wù)時(shí)間計(jì)時(shí)器(分鐘)-->
 <Timer>1</Timer>
 <!--固定:任務(wù)名稱-->
 <Name>獲取博客信息</Name>
 <!--固定:賬號(hào)-->
 <UserName></UserName>
 <!--固定:密碼-->
 <UserPwd></UserPwd>
 <!--固定:key-->
 <ApiKey></ApiKey>
 <!--固定:key-->
 <ApiUrl></ApiUrl>
 <!--固定:是否關(guān)閉任務(wù) 1:是 0:否-->
 <CloseTask>0</CloseTask>
 
<!--固定:描述-->
 <Des>獲取博客信息</Des>
 <!--自定義:其他配置信息-->
 <Other>
 <ShenNiuBuXing3>神牛步行3</ShenNiuBuXing3>
 </Other>
</TaskMain>

最后在CrossFiles.xml配置文件中添加TaskCore.Test.dll文件名稱如:

<!--
 CrossFiles指定對(duì)應(yīng)任務(wù)的dll文件,必須存在的文件
-->
<TaskMain>
 <File>TaskCore.Test.dll</File>
</TaskMain>

好了完成了,我們?cè)趙indows開(kāi)發(fā)環(huán)境上運(yùn)行看下效果圖:

到這里我們來(lái)簡(jiǎn)單總結(jié)下怎么使用TaskCore.MainForm插件,在自己項(xiàng)目中安裝TaskCore.Plugin的nuget包-》重寫(xiě)父類TPlugin的TPlugin_Load()方法-》生成自己的項(xiàng)目,拷貝項(xiàng)目的dll到TaskCore.MainForm運(yùn)行包中-》在運(yùn)行包中PluginXml文件夾中增加任務(wù)子類相同類名的xml文件并配置如上的配置信息-》增加CrossFiles.xml中的任務(wù)dll文件配置-》使用命令dotnet TaskCore.MainForm.dll運(yùn)行服務(wù)插件,挺簡(jiǎn)單的吧

. win7和ubuntu16.04運(yùn)行TaskCore.MainForm的兩種方式和測(cè)試截圖(也可認(rèn)為.netcore項(xiàng)目在win7和ubuntu系統(tǒng)運(yùn)行的兩種方式)

由于環(huán)境影響,這里跨平臺(tái)運(yùn)行測(cè)試我只測(cè)試win7和ubuntu16.04,其他系統(tǒng)的發(fā)布測(cè)試希望朋友們?cè)谑褂眠^(guò)程中得到結(jié)果告知我下謝謝;先來(lái)講在win7中運(yùn)行:

1. 安裝了netcore sdk環(huán)境的發(fā)布運(yùn)行

安裝了sdk后直接可以在cmd命令中dotnet TaskCore.MainForm.dll來(lái)運(yùn)行服務(wù),開(kāi)篇上面講解的示例都是在安裝了sdk后的截圖,服務(wù)運(yùn)行所需要的文件如圖:

就只有這些文件(當(dāng)然程序需要的某些平臺(tái)依賴項(xiàng)使用的是安裝的sdk中的文件,所以看起來(lái)很少實(shí)際應(yīng)該包含netcore sdk里面的文件才能運(yùn)行),通過(guò)命令運(yùn)行的效果圖:

2. 未安裝netcore sdk環(huán)境的發(fā)布運(yùn)行

在為安裝sdk平臺(tái)上系統(tǒng)上運(yùn)行才是重點(diǎn),這樣才可以說(shuō)是跨平臺(tái);首先,為了更好看效果我們復(fù)制一份如圖的兩個(gè)文件到TaskCore.MainForm01文件夾中:

沒(méi)錯(cuò),只需要這兩個(gè)文件,然后我們需要修改project.json文件的內(nèi)容如下注釋的地方:

{
 "version": "1.0.0-*",
 "buildOptions": {
 "emitEntryPoint": true
 },

 "dependencies": {
 "Microsoft.NETCore.App": {
 //"type": "platform", 跨平臺(tái)發(fā)布需要注釋
 "version": "1.0.0"
 },
 "System.IO.FileSystem": "4.0.1",
 "System.Reflection": "4.1.0",
 "System.Text.Encoding.CodePages": "4.0.1",
 "System.Threading.Timer": "4.0.1",
 "System.Xml.XDocument": "4.0.11",
 "TaskCore.Plugin": "1.0.0"
 },

 "frameworks": {
 "netcoreapp1.0": {
 "imports": "dnxcore50"
 }
 },
 //跨平臺(tái)發(fā)布需要添加如下節(jié)點(diǎn)
 "runtimes": {
 "ubuntu.16.04-x64": { }, //運(yùn)行在ubuntu.16.04的64位系統(tǒng)
 "win7-x64": { } //運(yùn)行在win7的64位系統(tǒng)
 }
}

然后使用cmd分別錄入并回車運(yùn)行指令dotnet restore此時(shí)TaskCore.MainForm01文件夾中會(huì)自動(dòng)生成一個(gè)project.lock.json文件(大家注意看下),然后再錄入指令dotnet publish -r win7-x64,可以看到命令窗信息如:

就表示成功了,并且有返回生成運(yùn)行文件的路徑,我們按照路徑找到生成的文件publish文件夾,里面沒(méi)有PluginXml配置文件夾和配置文件和測(cè)試項(xiàng)目TaskCore.Test.dll,我們?yōu)榱朔奖阒苯訌?fù)制上面配置好的配置文件到publish文件夾中如下截圖就是生成的發(fā)布文件:

沒(méi)錯(cuò)TaskCore.MainForm01.exe這個(gè)就是自動(dòng)生成的運(yùn)行文件,然后我們雙擊運(yùn)行效果圖:

運(yùn)行成功了,有朋友會(huì)問(wèn)您之前系統(tǒng)不是安裝了sdk么,這種測(cè)試能算么,我想說(shuō)的是這個(gè)我通過(guò)QQ發(fā)給qq群里面的朋友@南宮亦琦(不要怪我貼出了您的昵稱)測(cè)試過(guò)了,她沒(méi)有安裝過(guò)sdk的;

ubuntu16.04運(yùn)行:

1. 安裝了netcore sdk環(huán)境的發(fā)布運(yùn)行

首先,我們需要把在win7上生成的項(xiàng)目復(fù)制到ubuntu系統(tǒng)磁盤中(我們使用上面配置好的TaskCore.MainForm包),我這里采用共享目錄的方式把文件拷貝到ubuntu系統(tǒng)磁盤上,如圖:

然后,鼠標(biāo)右鍵點(diǎn)擊空白地方,選擇“在終端打開(kāi)”,然后在窗體中錄入如下指令dotnet TaskCore.MainForm.dll,能看到如下運(yùn)行起的結(jié)果:

這個(gè)命令方式是不是很上面win7上的方式很相同,本來(lái)就是一樣的,只要安裝了.netcore sdk這種方式幾乎可以共用

2. 未安裝netcore sdk環(huán)境的發(fā)布運(yùn)行

不安裝sdk環(huán)境運(yùn)行才是咋們需要關(guān)注的,下面就來(lái)看下怎么生成再ubuntu系統(tǒng)上能運(yùn)行的文件;我們復(fù)制一份上面的TaskCore.MainForm01項(xiàng)目到TaskCore.MainForm02中來(lái)測(cè)試,由于之前我們?cè)谥v生成win7執(zhí)行文件時(shí)候,執(zhí)行了命令dotnet restore和dotnet publish -r win7-x64命令所以文件中有project.lock和bin文件夾,為了測(cè)試我們需要?jiǎng)h除掉部分文件,只剩下如圖文件,這里需要注意的是之前已經(jīng)配置過(guò)project.xml我們無(wú)需在修改了:

然后,分別執(zhí)行和生成win7運(yùn)行文件幾乎相同的命令dotnet restore和dotnet publish -r ubuntu.16.04-x64不同之處在于生成的文件存放的位置不同和使用的運(yùn)行環(huán)境不同,運(yùn)行結(jié)果如圖:

publish文件夾中的文件就是在ubuntu系統(tǒng)執(zhí)行的文件,然后我們需要把任務(wù)配置文件夾PluginXml和測(cè)試項(xiàng)目TaskCore.Test.dll復(fù)制到該目錄中,再來(lái)咋們通過(guò)共享吧TaskCore.MainForm02目錄中的publish復(fù)制到ubuntu中;然后我們需要把TaskCore.MainForm02可執(zhí)行文件設(shè)置下權(quán)限,鼠標(biāo)右鍵點(diǎn)擊TaskCore.MainForm02可執(zhí)行文件,選擇“屬性”,再選擇“權(quán)限”選項(xiàng)卡,勾選“允許作為程序執(zhí)行”,如圖:

然后,我們右鍵文件夾中空白處,選擇“在終端打開(kāi)”,再執(zhí)行如下命令./TaskCore.MainForm02,最后看運(yùn)行效果圖:

好了,發(fā)布在ubuntu系統(tǒng)上執(zhí)行文件和運(yùn)行的步奏就這些,幾乎和win7上相同

. 框架代碼解讀及感悟

怎么使用跨平臺(tái)TaskCore.MainForm任務(wù)框架講解完了,下面來(lái)具體看下主要代碼Program.cs文件中:

namespace TaskCore.MainForm
{
 /// <summary>
 /// author 神牛步行3
 /// contact 841202396@qq.com
 /// des TaskCore.MainForm跨平臺(tái)插件由神牛步行3提供
 /// </summary>
 public class Program
 {

 private static Dictionary<string, MoAssembly> dicTasks = new Dictionary<string, MoAssembly>();

 public static void Main(string[] args)
 {
 //注冊(cè)編碼,防止亂碼
 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

 //初始化程序集文件
 _Init();

 //是否繼續(xù)開(kāi)啟任務(wù),默認(rèn)沒(méi)有待執(zhí)行任務(wù),不提示
 if (dicTasks.Count <= 0) { _LoopAlert("是否退出?(Y/N)"); return; }
 _LoopAlert("是否開(kāi)始執(zhí)行任務(wù)?(Y / N)");

 //執(zhí)行任務(wù)
 foreach (var item in dicTasks.Values)
 {
 //使用Task防止異常后相互影響
 Task.Run(() =>
 {
 try
 {

 //創(chuàng)建任務(wù)對(duì)象
 var tp = item.Asm.CreateInstance(item.FullName) as TPlugin;
 if (!string.IsNullOrEmpty(tp.XmlConfig.TpError)) { _Alert($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm")}:{tp.XmlConfig.Name} - 異常信息:{tp.XmlConfig.TpError}"); }
 else
 {

 //timer定時(shí)器
 var timer = new Timer((param) =>
 {
 var msg = $"{DateTime.Now.ToString("yyyy/MM/dd HH:mm")}:{tp.XmlConfig.Name}";
 try
 {
 var tpObj = param as TPlugin;
 //是否關(guān)閉暫停任務(wù)
 if (tpObj.XmlConfig.CloseTask) { return; }
 _Alert($"{msg} - 開(kāi)始執(zhí)行...{tp.XmlConfig.Timer}分鐘一次");
 //任務(wù)入口
 tpObj.TPlugin_Load();
 }
 catch (Exception ex) { _Alert($"{msg} - 異常信息:{ex.Message}"); }
 }, tp, 0, 1000 * 60 * tp.XmlConfig.Timer);
 }

 }
 catch (Exception ex)
 {
 _Alert($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm")}:{item.Name} - 異常信息:{ex.Message}");
 }
 });
 }
 _LoopAlert("正在監(jiān)控執(zhí)行的任務(wù),是否退出?(Y / N)");
 }

 /// <summary>
 /// 初始化程序集文件
 /// </summary>
 private static void _Init()
 {
 try
 {

 _Alert("初始化任務(wù)中...");
 //獲取文件
 var files = PublicClass._GetPluginFile("");
 if (files.Length <= 0) { _Alert("未能找到可用的程序集,請(qǐng)檢查配置"); return; }

 //讀取任務(wù)文件
 _Alert("讀取CrossFiles.xml配置中...");
 var baseAddr = Path.Combine(Directory.GetCurrentDirectory(), "PluginXml", "CrossFiles.xml");
 var doc = XDocument.Load(baseAddr);
 var fileables = files.AsEnumerable();
 var taskFiles = new List<FileInfo>();
 foreach (var item in doc.Root.Nodes())
 {
 var crossFile = item.ToString().ToUpper();
 var choiceFiles = fileables.Where(b => crossFile.Contains(b.Name.ToUpper()));
 if (!choiceFiles.Any()) { continue; }

 taskFiles.AddRange(choiceFiles);
 }

 //展示文件信息
 _Alert($"待遍歷{taskFiles.Count}個(gè)文件信息...");
 foreach (var item in taskFiles.OrderBy(b => b.CreationTime))
 {
 var asmName = new AssemblyName($"{item.Name.Replace(".dll", "")}");
 Assembly sm = Assembly.Load(asmName);
 if (sm == null) { continue; }
 var ts = sm.GetTypes();
 //判斷特定的任務(wù)類,加入任務(wù)dic
 foreach (var t in ts.Where(b => b.Name != "TPlugin" && b.GetMethod("TPlugin_Load") != null))
 {

 dicTasks.Add(
 t.FullName,
 new MoAssembly
 {
 Asm = sm,
 FullName = t.FullName,
 Name = t.Name
 });
 }
 }
 _Alert($"獲取待執(zhí)行任務(wù)量:{dicTasks.Count}個(gè)");
 }
 catch (Exception ex)
 {
 _Alert($"異常信息:{ ex.Message}");
 }
 }

 /// <summary>
 /// 消息提醒
 /// </summary>
 /// <param name="msg">提示信息</param>
 /// <param name="isReadLine">是否需要用戶輸入指令</param>
 /// <returns>用戶錄入的指令</returns>
 private static string _Alert(string msg = "神牛步行3-消息提醒", bool isReadLine = false)
 {
 Console.WriteLine(msg);
 if (isReadLine) { return Console.ReadLine(); }
 return "";
 }

 private static void _LoopAlert(string msg = "是否開(kāi)始執(zhí)行任務(wù)?(Y/N)")
 {
 do
 {
 var readKey = _Alert(msg, true);
 if (readKey.ToUpper().Contains("Y")) { break; }
 } while (true);
 }
 }

 public class MoAssembly
 {
 public Assembly Asm { get; set; }
 public string FullName { get; set; }

 public string Name { get; set; }
 }
}

TPlugin.cs文件中代碼:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace TaskCore.Plugin
{
 /// <summary>
 /// 插件基類
 /// </summary>
 public class TPlugin : IDisposable
 {

 public TPlugin()
 {

 XmlConfig = _InitConfig();
 }

 #region 初始化Xml配置文件 _InitConfig +XmlConfig

 /// <summary>
 /// xml配置信息
 /// </summary>
 public XmlConfig XmlConfig;


 /// <summary>
 /// 初始化配置信息
 /// </summary>
 /// <param name="configPath">配置文件對(duì)應(yīng)路徑</param>
 /// <returns></returns>
 public virtual XmlConfig _InitConfig(string configPath = "")
 {
 XmlConfig config = new XmlConfig();
 config.Timer = 1;
 config.Name = this.GetType().Name;
 try
 {

 if (string.IsNullOrEmpty(configPath))
 {

 //默認(rèn)各個(gè)dllXml配置
 var defaultConfigFolder = "PluginXml";
 var baseAddr = Directory.GetCurrentDirectory();
 configPath = Path.Combine(baseAddr, defaultConfigFolder, config.Name + ".xml");
 }

 var doc = XDocument.Load(configPath);
 config.doc = doc;
 var taskMain = doc.Root;

 config.Timer = Convert.ToInt32(taskMain.Element(XName.Get("Timer", "")).Value);
 config.Name = taskMain.Element(XName.Get("Name", "")).Value;
 config.Des = taskMain.Element(XName.Get("Des", "")).Value;

 config.UserName = taskMain.Element(XName.Get("UserName", "")).Value;
 config.UserPwd = taskMain.Element(XName.Get("UserPwd", "")).Value;
 config.ApiKey = taskMain.Element(XName.Get("ApiKey", "")).Value;
 config.ApiUrl = taskMain.Element(XName.Get("ApiUrl", "")).Value;
 config.CloseTask = taskMain.Element(XName.Get("CloseTask", "")).Value == "1";

 }
 catch (Exception ex)
 {
 config.TpError = ex.Message;
 PublicClass._WriteLog($"{config.Name}初始化配置信息異常:{ex.Message}", "BaseLog");
 throw new Exception(ex.Message);
 }
 return config;
 }
 #endregion

 #region 初始化-開(kāi)始加載 _Load

 /// <summary>
 /// 初始化-開(kāi)始起
 /// </summary>
 public virtual void TPlugin_Load()
 {

 PublicClass._WriteLog("測(cè)試");
 }

 #endregion

 #region 釋放資源

 public void Dispose()
 {

 GC.SuppressFinalize(this);//不需要再調(diào)用本對(duì)象的Finalize方法
 }

 public virtual void Dispose(Action action)
 {

 action();
 }

 #endregion
 }

 #region 配置文件 XmlConfig

 public class XmlConfig
 {
 public XmlConfig()
 {

 }

 /// <summary>
 /// 定制器時(shí)間(分鐘)
 /// </summary>
 public int Timer { get; set; }

 /// <summary>
 /// 運(yùn)行名稱
 /// </summary>
 public string Name { get; set; }

 /// <summary>
 /// 描述(第一次獲取dll描述,后面獲取xml配置文件描述)
 /// </summary>
 public string Des { get; set; }

 /// <summary>
 /// 接口賬號(hào)
 /// </summary>
 public string UserName { get; set; }

 /// <summary>
 /// 接口密碼
 /// </summary>
 public string UserPwd { get; set; }

 /// <summary>
 /// 接口秘鑰
 /// </summary>
 public string ApiKey { get; set; }

 /// <summary>
 /// 接口地址
 /// </summary>
 public string ApiUrl { get; set; }

 /// <summary>
 /// 是否關(guān)閉任務(wù)
 /// </summary>
 public bool CloseTask { get; set; }

 /// <summary>
 /// 插件中錯(cuò)誤
 /// </summary>
 public string TpError { get; set; }


 /// <summary>
 /// xml信息
 /// </summary>
 public XDocument doc { get; set; }
 }

 #endregion
}

具體的說(shuō)明和邏輯處理代碼中都有注釋,各位可以詳細(xì)看下;這里要訴說(shuō)的是該框架主要原理是動(dòng)態(tài)加載任務(wù)dll來(lái)創(chuàng)建對(duì)象,netcore的程序集類Assembly不像framework里面的Assembly一樣那么多可以用方法,我這里用的Assembly.Load(),netcore只能加載當(dāng)前系統(tǒng)根目錄的dll(這里我花了幾個(gè)小時(shí)測(cè)試,有不同結(jié)果的朋友,請(qǐng)及時(shí)聯(lián)系我謝謝),框架使用Task.Run()方法創(chuàng)建不同任務(wù),實(shí)現(xiàn)并行執(zhí)行的效果,并且各個(gè)容易出錯(cuò)地方使用try...catch來(lái)容錯(cuò),避免了某個(gè)子任務(wù)異常后,導(dǎo)致框架全部中斷運(yùn)行,個(gè)人覺(jué)得其實(shí)還是不錯(cuò)的是吧;

下面給出幾個(gè)不同環(huán)境下的壓縮包,以供使用和參考:

TaskCore.MainForm-純文件 TaskCore.MainForm01 git源碼地址

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

開(kāi)源跨平臺(tái)運(yùn)行服務(wù)插件TaskCore.MainForm

開(kāi)源跨平臺(tái)運(yùn)行服務(wù)插件TaskCore.MainForm:本次將要很大家分享的是一個(gè)跨平臺(tái)運(yùn)行的服務(wù)插件 - TaskCore.MainForm,此框架是使用.netcore來(lái)寫(xiě)的,現(xiàn)在netcore已經(jīng)支持很多系統(tǒng)平臺(tái)運(yùn)行了,所以將以前的Task.MainForm改良成跨平臺(tái)的服務(wù)共大家使用和相互交流;本來(lái)這篇應(yīng)該分享的是nginx+iis+
推薦度:
  • 熱門焦點(diǎn)

最新推薦

猜你喜歡

熱門推薦

專題
Top