一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - ASP.NET教程 - 開源跨平臺運行服務(wù)插件TaskCore.MainForm

開源跨平臺運行服務(wù)插件TaskCore.MainForm

2020-05-09 12:44神牛步行3 ASP.NET教程

這篇文章主要為大家詳細介紹了開源跨平臺運行服務(wù)插件TaskCore.MainForm的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下

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

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

. 如何生成nuget包和使用開源框架TaskCore.MainForm

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

. 框架代碼解讀及感悟

下面一步一個腳印的來分享:

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

首先,咋們先來認識下項目源碼的工程目錄結(jié)構(gòu)如圖:

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

如果安裝了.netcore sdk的話在windows上您只需要上面截圖的文件就能運行插件了;再來我們在已經(jīng)安裝過core sdk的win7系統(tǒng)上執(zhí)行一下如下命令dotnet TaskCore.MainForm.dll就能看到如圖的效果:

開源跨平臺運行服務(wù)插件TaskCore.MainForm

沒錯這就是插件運行起來的效果圖,因為.netcore現(xiàn)目前暫時沒有提供類似于winform那樣的皮膚界面效果,所有只能通過命令行來做跨平臺運行程序

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

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

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

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

并且project.json文件中自動添加了依賴項:

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

使用TaskCore.MainForm:

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

BlogsObj.cs:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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}測試引用nuget包");
 
   }
   catch (Exception ex)
   {
    sbLog.Append($"異常信息:{ex.Message}");
   }
   finally
   {
 
    PublicClass._WriteLog(sbLog.ToString(), this.XmlConfig.Name);
   }
  }
 }
}

BlogsObj01.cs:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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);
  }
 }
}

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!--
 1.xml配置模板
 2.utf-8文件
 3.復制到程序根目錄下面PluginXml文件夾下
 4.每個任務(wù)建議創(chuàng)建和程序dll名稱相同xml配置文件
-->
<TaskMain>
 <!--固定:執(zhí)行任務(wù)時間計時器(分鐘)-->
 <Timer>1</Timer>
 <!--固定:任務(wù)名稱-->
 <Name>獲取博客信息</Name>
 <!--固定:賬號-->
 <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文件名稱如:

?
1
2
3
4
5
6
<!--
 CrossFiles指定對應(yīng)任務(wù)的dll文件,必須存在的文件
-->
<TaskMain>
 <File>TaskCore.Test.dll</File>
</TaskMain>

好了完成了,我們在windows開發(fā)環(huán)境上運行看下效果圖:

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

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

由于環(huán)境影響,這里跨平臺運行測試我只測試win7和ubuntu16.04,其他系統(tǒng)的發(fā)布測試希望朋友們在使用過程中得到結(jié)果告知我下謝謝;先來講在win7中運行:

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

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
 "version": "1.0.0-*",
 "buildOptions": {
 "emitEntryPoint": true
 },
 
 "dependencies": {
 "Microsoft.NETCore.App": {
  //"type": "platform", 跨平臺發(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"
 }
 },
 //跨平臺發(fā)布需要添加如下節(jié)點
 "runtimes": {
 "ubuntu.16.04-x64": { }, //運行在ubuntu.16.04的64位系統(tǒng)
 "win7-x64": { } //運行在win7的64位系統(tǒng)
 }
}

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

就表示成功了,并且有返回生成運行文件的路徑,我們按照路徑找到生成的文件publish文件夾,里面沒有PluginXml配置文件夾和配置文件和測試項目TaskCore.Test.dll,我們?yōu)榱朔奖阒苯訌椭粕厦媾渲煤玫呐渲梦募絧ublish文件夾中如下截圖就是生成的發(fā)布文件:

開源跨平臺運行服務(wù)插件TaskCore.MainForm

沒錯TaskCore.MainForm01.exe這個就是自動生成的運行文件,然后我們雙擊運行效果圖:

開源跨平臺運行服務(wù)插件TaskCore.MainForm

運行成功了,有朋友會問您之前系統(tǒng)不是安裝了sdk么,這種測試能算么,我想說的是這個我通過QQ發(fā)給qq群里面的朋友@南宮亦琦(不要怪我貼出了您的昵稱)測試過了,她沒有安裝過sdk的;

ubuntu16.04運行:

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

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

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

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

開源跨平臺運行服務(wù)插件TaskCore.MainForm

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

. 框架代碼解讀及感悟

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

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
namespace TaskCore.MainForm
{
 /// <summary>
 /// author 神牛步行3
 /// contact [email protected]
 /// des TaskCore.MainForm跨平臺插件由神牛步行3提供
 /// </summary>
 public class Program
 {
 
  private static Dictionary<string, MoAssembly> dicTasks = new Dictionary<string, MoAssembly>();
 
  public static void Main(string[] args)
  {
   //注冊編碼,防止亂碼
   Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
 
   //初始化程序集文件
   _Init();
 
   //是否繼續(xù)開啟任務(wù),默認沒有待執(zhí)行任務(wù),不提示
   if (dicTasks.Count <= 0) { _LoopAlert("是否退出?(Y/N)"); return; }
   _LoopAlert("是否開始執(zhí)行任務(wù)?(Y / N)");
 
   //執(zhí)行任務(wù)
   foreach (var item in dicTasks.Values)
   {
    //使用Task防止異常后相互影響
    Task.Run(() =>
    {
     try
     {
 
      //創(chuàng)建任務(wù)對象
      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定時器
       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} - 開始執(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("未能找到可用的程序集,請檢查配置"); 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}個文件信息...");
    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}個");
   }
   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 = "是否開始執(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文件中代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
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">配置文件對應(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))
    {
 
     //默認各個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 初始化-開始加載 _Load
 
  /// <summary>
  /// 初始化-開始起
  /// </summary>
  public virtual void TPlugin_Load()
  {
 
   PublicClass._WriteLog("測試");
  }
 
  #endregion
 
  #region 釋放資源
 
  public void Dispose()
  {
 
   GC.SuppressFinalize(this);//不需要再調(diào)用本對象的Finalize方法
  }
 
  public virtual void Dispose(Action action)
  {
 
   action();
  }
 
  #endregion
 }
 
 #region 配置文件 XmlConfig
 
 public class XmlConfig
 {
  public XmlConfig()
  {
 
  }
 
  /// <summary>
  /// 定制器時間(分鐘)
  /// </summary>
  public int Timer { get; set; }
 
  /// <summary>
  /// 運行名稱
  /// </summary>
  public string Name { get; set; }
 
  /// <summary>
  /// 描述(第一次獲取dll描述,后面獲取xml配置文件描述)
  /// </summary>
  public string Des { get; set; }
 
  /// <summary>
  /// 接口賬號
  /// </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>
  /// 插件中錯誤
  /// </summary>
  public string TpError { get; set; }
 
 
  /// <summary>
  /// xml信息
  /// </summary>
  public XDocument doc { get; set; }
 }
 
 #endregion
}

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

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

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://www.cnblogs.com/wangrudong003/p/5952388.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本免费一区二区三区a区 日本免费三片在线观看 | 成人永久免费福利视频网站 | 91yellow吧字幕网zmff7 | 欧美草逼视频 | 精品一卡2卡3卡4卡5卡亚洲 | 波多野 在线 | 精品精品国产yyy5857香蕉 | 草草草在线 | 成人欧美一区二区三区 | 午夜理论电影在线观看亚洲 | 国产亚洲精品美女 | luan小说 | 国产成人h视频在线播放网站 | 6个老师的尿奴 | 国语刺激对白勾搭视频在线观看 | 日本在线观看www免费 | 小柔的性放荡羞辱日记 | 五月激情丁香婷婷综合第九 | japonensis中国东北老人 | 性一交一乱一伧老太 | 免费尤物视频 | nxgx在线观看国产中文 | tube日本高清老少配 | 白白国产永久免费视频 | 国产精品久久久久久影视 | 国产成人久久精品区一区二区 | 国产馆| 国产成人www免费人成看片 | 久久免费看少妇高潮A片2012 | 视频高清在线观看 | 久久视频这有精品63在线国产 | 亚洲精品视频久久 | 亚洲视频第一页 | 日韩成a人片在线观看日本 日韩不卡一区二区 | 青青青青久久国产片免费精品 | 免费观看俄罗斯特黄特色 | 三年片韩国在线观看 | 女学生被老师调教在教室 | 草草剧场 | 亚洲成综合人影院在院播放 | 久久中文字幕乱码免费 |