>

享受二个赞助类,八十四线程编制程序连串云顶

- 编辑:云顶娱乐yd2221 -

享受二个赞助类,八十四线程编制程序连串云顶

作者水平有限,倘若不当迎接各位商议指正!

自然想趁待业时期的小运读完《Multithreading with C# Cookbook Second Edition》那本书,並且享受做的连锁笔记;不过出于作者近来专门的学业规划和身体原因,也许前段时间都未曾时间来更新这么些连串,没办法达成几天风度翩翩更。请大家多多饱含!不过作者必将这一个类别全部翻新实现的!感激大家的支撑!

 

 1  Bitmap bit= new Bitmap(@"" + Path);//给图片加边框
 2  //Bitmap bit = new Bitmap(Screen.AllScreens[0].Bounds.Size.Width, Screen.AllScreens[0].Bounds.Size.Height);//给当前桌面图加边框
 3  float w = (float)(bit.Width * 0.2);//边框的宽度,可取任意值
 4   using (Graphics g = Graphics.FromImage(bit))
 5   {
 6       // g.CopyFromScreen(0, 0, 0, 0, Screen.AllScreens[0].Bounds.Size);//抓取背景图
 7         using (Pen pen = new Pen(Color.White, w))
 8        { 
 9        //g.DrawRectangle(pen, new Rectangle(0, 0, Screen.AllScreens[0].Bounds.Size.Width, Screen.AllScreens[0].Bounds.Size.Height));//给当前桌面画白框
10         //g.DrawRectangle(pen, new Rectangle(0, 0, Math.Abs(bit.Width), Math.Abs(bit.Height)));//加边框
11          g.DrawEllipse(pen, new Rectangle(0, 0, Math.Abs(bit.Width), Math.Abs(bit.Height)));//加椭圆边框
12           g.Dispose();
13         // pic.BackgroundImage = bit;
14        } 
15    }

四、宗旨本领详细

  1.SAEA.RedisSocket:这几个是依据SAEA.Socket达成的Redis编解码命令的客商端,近日打包了多边的redis数据操作命令和总体的redis cluster命令,更加多详细可参看。

  2.SAEA.WebApi:那么些是依据SAEA.Socket完毕的http编解码命令的服务端,如今已达成了get、post的管理,扶助三种form的解码;何况已融为朝气蓬勃体了mvc风格的编码框架,越来越多详细可参谋。

  3.LayUI:这么些是逸事中面向后端开采人士的Web框架,制版上是仿Bootstrap的风骨,集成了大批量的插件,能够高速完结相关的web页面成效,越来越多详细可参照:。

不过,这里咱们开掘三个主题材料,那就是,在泛型函数里,使用泛型对象的时候,大家发掘指标都以object类型的。

1.5 将APM格局调换为天职

在前面包车型大巴章节中,介绍了基于IAsyncResult接口完毕了BeginXXXX/EndXXXX方法的就叫APM格局。APM情势极其古老,那么什么样将它调换为TAP格局吧?对于普及的二种APM格局异步职务,大家平日选择选择Task.Factory.FromAsync()情势来促成将APM模式转换为TAP模式

亲自过问代码如下所示,比较轻巧不作过多介绍。

static void Main(string[] args)
{
    int threadId;
    AsynchronousTask d = Test;
    IncompatibleAsychronousTask e = Test;

    // 使用 Task.Factory.FromAsync方法 转换为Task
    WriteLine("Option 1");
    Task<string> task = Task<string>.Factory.FromAsync(d.BeginInvoke("异步任务线程", CallBack, "委托异步调用"), d.EndInvoke);

    task.ContinueWith(t => WriteLine($"回调函数执行完毕,现在运行续接函数!结果:{t.Result}"));

    while (!task.IsCompleted)
    {
        WriteLine(task.Status);
        Sleep(TimeSpan.FromSeconds(0.5));
    }
    WriteLine(task.Status);
    Sleep(TimeSpan.FromSeconds(1));

    WriteLine("----------------------------------------------");
    WriteLine();

    // 使用 Task.Factory.FromAsync重载方法 转换为Task
    WriteLine("Option 2");

    task = Task<string>.Factory.FromAsync(d.BeginInvoke,d.EndInvoke,"异步任务线程","委托异步调用");

    task.ContinueWith(t => WriteLine($"任务完成,现在运行续接函数!结果:{t.Result}"));

    while (!task.IsCompleted)
    {
        WriteLine(task.Status);
        Sleep(TimeSpan.FromSeconds(0.5));
    }
    WriteLine(task.Status);
    Sleep(TimeSpan.FromSeconds(1));

    WriteLine("----------------------------------------------");
    WriteLine();

    // 同样可以使用 FromAsync方法 将 BeginInvoke 转换为 IAsyncResult 最后转换为 Task
    WriteLine("Option 3");

    IAsyncResult ar = e.BeginInvoke(out threadId, CallBack, "委托异步调用");
    task = Task<string>.Factory.FromAsync(ar, _ => e.EndInvoke(out threadId, ar));

    task.ContinueWith(t => WriteLine($"任务完成,现在运行续接函数!结果:{t.Result},线程Id {threadId}"));

    while (!task.IsCompleted)
    {
        WriteLine(task.Status);
        Sleep(TimeSpan.FromSeconds(0.5));
    }
    WriteLine(task.Status);

    ReadLine();
}

delegate string AsynchronousTask(string threadName);
delegate string IncompatibleAsychronousTask(out int threadId);

static void CallBack(IAsyncResult ar)
{
    WriteLine("开始运行回调函数...");
    WriteLine($"传递给回调函数的状态{ar.AsyncState}");
    WriteLine($"是否为线程池线程:{CurrentThread.IsThreadPoolThread}");
    WriteLine($"线程池工作线程Id:{CurrentThread.ManagedThreadId}");
}

static string Test(string threadName)
{
    WriteLine("开始运行...");
    WriteLine($"是否为线程池线程:{CurrentThread.IsThreadPoolThread}");
    Sleep(TimeSpan.FromSeconds(2));

    CurrentThread.Name = threadName;
    return $"线程名:{CurrentThread.Name}";
}

static string Test(out int threadId)
{
    WriteLine("开始运行...");
    WriteLine($"是否为线程池线程:{CurrentThread.IsThreadPoolThread}");
    Sleep(TimeSpan.FromSeconds(2));

    threadId = CurrentThread.ManagedThreadId;
    return $"线程池线程工作Id是:{threadId}";
}

运营结果如下图所示。

云顶娱乐yd2221 1

TimeHelper(拾四人时间戳和时间的相互影响转变卡塔尔国:

 

一、简介

  方今因为做事须求,使用了某个单机版Redis的分界面化管理工科具,使用进度中那优伤的心得真正独有用过的人技术心得;为此笔者和小同伴策动动手三个Redis可视化工具,但是因为小同伴这两天干活比较忙,搞了大部分没一时间持续(会有延续,分界面不敢说,使用体验方面肯定要比现存的好卡塔尔;本身对wpf不是很熟,再想到十分久在此以前的web迅雷,就想入手完毕二个web版的Redis的分界面化管理工科具;近年来以此工具已最早成型,所以放出去分享一下。

切实选择方法如下:

1.9 相互运维职务

本节中举足轻重介绍了多少个格局的选取,贰个是等待组中全部职务都施行实现的Task.WhenAll()办法,另二个是只要组中多个主意试行完毕都实践的Task.WhenAny()方法。

现实接受,如下演示代码所示。

static void Main(string[] args)
{
    // 第一种方式 通过Task.WhenAll 等待所有任务运行完成
    var firstTask = new Task<int>(() => TaskMethod("First Task", 3));
    var secondTask = new Task<int>(() => TaskMethod("Second Task", 2));

    // 当firstTask 和 secondTask 运行完成后 才执行 whenAllTask的ContinueWith
    var whenAllTask = Task.WhenAll(firstTask, secondTask);
    whenAllTask.ContinueWith(t => WriteLine($"第一个任务答案为{t.Result[0]},第二个任务答案为{t.Result[1]}"), TaskContinuationOptions.OnlyOnRanToCompletion);

    firstTask.Start();
    secondTask.Start();

    Sleep(TimeSpan.FromSeconds(4));

    // 使用WhenAny方法  只要列表中有一个任务完成 那么该方法就会取出那个完成的任务
    var tasks = new List<Task<int>>();
    for (int i = 0; i < 4; i++)
    {
        int counter = 1;
        var task = new Task<int>(() => TaskMethod($"Task {counter}",counter));
        tasks.Add(task);
        task.Start();
    }

    while (tasks.Count > 0)
    {
        var completedTask = Task.WhenAny(tasks).Result;
        tasks.Remove(completedTask);
        WriteLine($"一个任务已经完成,结果为 {completedTask.Result}");
    }

    ReadLine();
}

static int TaskMethod(string name, int seconds)
{
    WriteLine($"任务运行在{CurrentThread.ManagedThreadId}上. 是否为线程池线程:{CurrentThread.IsThreadPoolThread}");

    Sleep(TimeSpan.FromSeconds(seconds));
    return 42 * seconds;
}

运营结果如下图所示。

云顶娱乐yd2221 2

我们在编写程序的历程中,平日会用到有个别方法,小编只是把那几个办法结合一下,方便使用,这段日子有md5,sha1,aes加解密,身份ID评释,敏感词过滤,文件减少,图片与base64相互转换,时间戳与时间相互转变,轻便的http乞请,简单的ftp上传下载,依据初叶和结尾字符串截取字符串等等,后续策画把日记记录,支付宝和Wechat支付进行增加,方便使用,假诺您在编制程序的经过中有比较常用的点子,能够建议来,大家得以协作来宏观这几个扶持类,如若有不法规之处,恳请指正争辩,多谢大家,喜欢能够分享哦。

 

三、开辟简单介绍

  上边根本是依据SAEA.Socket通讯框架中的SAEA.RedisSocket、SAEA.WebApi四个零器件来实现redis通讯、webserver以至仿asp.net mvc的快速风格的后端程序,web端使用的是layui+ajax。项目源码结构:

  云顶娱乐yd2221 3

 

也很简单,反射就能够了。


上边介绍那个扶助类方今有些的有的艺术:

二、基本采取手续

  首先下载包,并解压展开,如下图:

  云顶娱乐yd2221 4

  接下去双击文件WebRedisManager.exe运转,假诺不可能运营以来,恐怕要求安装.net framework 4.5,成功开辟分界面如下:

  云顶娱乐yd2221 5

  然后打开浏览器,地址栏按上面提示输入url,分界面如下:

  云顶娱乐yd2221 6

  当时就能够增加redis服务器了:

  云顶娱乐yd2221 7

  增加家成业就后会自动呈现在左侧:

  云顶娱乐yd2221 8

  云顶娱乐yd2221 9

  云顶娱乐yd2221 10

  一些符合规律化的增加和删除改查的成效都有,最近还或许有大器晚成部分询问作用、集群管理等还没实现,现在查询项暗中认可都以四十多少个,后续再逐步加上吧。  

泛型的羁绊

  • 1.1 简介
  • 1.2 创立职分
  • 1.3 使用职务奉行基本的操作
  • 1.4 组合义务
  • 1.5 将APM情势调换为天职
  • 1.6 将EAP形式调换为天职
  • 1.7 达成撤废选项
  • 1.8 管理任务中的非常
  • 1.9 互相运营任务
  • 1.10 使用TaskScheduler配置职分奉行
  • 参照书籍
  • 小编水平有限,如果不当迎接各位评论指正!

云顶娱乐yd2221 11

五、完整封装及源代码分享

享受二个赞助类,八十四线程编制程序连串云顶娱乐yd2221:。  这么些连串按SAEA简洁高效的点子开展编码的,比超级多地点都施用的暗中同意值,无论是查看代码依旧一连衔接都相当的轻便方便,上面是本项目标启航源码:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             ConsoleHelper.Title = "WebRedisManagerService";
 6 
 7             MvcApplication mvcApplication = new MvcApplication(10240, 3000);
 8 
 9             mvcApplication.Start();
10 
11             ConsoleHelper.WriteLine("WebRedisManager服务已启动");
12 
13             ConsoleHelper.WriteLine("http://localhost:39654/html/index.html,按回车结束......");
14 
15             Process.Start("http://localhost:39654/html/index.html");
16 
17             ConsoleHelper.ReadLine();
18         }
19     }

  更加多源码请访谈 

 

转载请标注本文来源:
更加多内容招待star小编的github:
万一开掘本文有哪些难点和任何提出,也随即接待调换~

泛型的行使,开篇已经说了,首要用在加强代码的可重用性、类型安全性和频率上。

1.6 将EAP情势调换为职务

在上几章中有涉及,通过BackgroundWorker类经过事件的不二等秘书诀达成的异步,大家叫它EAP情势。那么什么样将EAP格局调换为任务吗?很简单,大家只须求经过TaskCompletionSource类,就可以将EAP情势调换为职分。

示范代码如下所示。

static void Main(string[] args)
{
    var tcs = new TaskCompletionSource<int>();

    var worker = new BackgroundWorker();
    worker.DoWork += (sender, eventArgs) =>
    {
        eventArgs.Result = TaskMethod("后台工作", 5);
    };

    // 通过此方法 将EAP模式转换为 任务
    worker.RunWorkerCompleted += (sender, eventArgs) =>
    {
        if (eventArgs.Error != null)
        {
            tcs.SetException(eventArgs.Error);
        }
        else if (eventArgs.Cancelled)
        {
            tcs.SetCanceled();
        }
        else
        {
            tcs.SetResult((int)eventArgs.Result);
        }
    };

    worker.RunWorkerAsync();

    // 调用结果
    int result = tcs.Task.Result;

    WriteLine($"结果是:{result}");

    ReadLine();
}

static int TaskMethod(string name, int seconds)
{
    WriteLine($"任务{name}运行在线程{CurrentThread.ManagedThreadId}上. 是否为线程池线程{CurrentThread.IsThreadPoolThread}");

    Sleep(TimeSpan.FromSeconds(seconds));

    return 42 * seconds;
}

运作结果如下图所示。

云顶娱乐yd2221 12

 

public class Generic
{
    public String Name;
}

public class Generic<T>
{
    public T Name;
}

1.3 使用任务实践基本的操作

在本节中,使用职责实施基本的操作,并且获得任务实施到位后的结果值。本节内容比较容易,在这里不做过多介绍。

示范代码如下,在主线程中要博得结果值,常用的办法正是访谈task.Result属性,假如职分线程尚未施行实现,那么会阻塞主线程,直到线程施行完。借使职分线程施行达成,那么将直接获得运算的结果值。

Task 3中,使用了task.Status来打字与印刷线程的气象,线程各个景况的切切实实意思,就要下风姿浪漫节中牵线。

static void Main(string[] args)
{
    // 直接执行方法 作为参照
    TaskMethod("主线程任务");

    // 访问 Result属性 达到运行结果
    Task<int> task = CreateTask("Task 1");
    task.Start();
    int result = task.Result;
    WriteLine($"运算结果: {result}");

    // 使用当前线程,同步执行任务
    task = CreateTask("Task 2");
    task.RunSynchronously();
    result = task.Result;
    WriteLine($"运算结果:{result}");

    // 通过循环等待 获取运行结果
    task = CreateTask("Task 3");
    WriteLine(task.Status);
    task.Start();

    while (!task.IsCompleted)
    {
        WriteLine(task.Status);
        Sleep(TimeSpan.FromSeconds(0.5));
    }

    WriteLine(task.Status);
    result = task.Result;
    WriteLine($"运算结果:{result}");

    Console.ReadLine();
}

static Task<int> CreateTask(string name)
{
    return new Task<int>(() => TaskMethod(name));
}

static int TaskMethod(string name)
{
    WriteLine($"{name} 运行在线程 {CurrentThread.ManagedThreadId}上. 是否为线程池线程 {CurrentThread.IsThreadPoolThread}");

    Sleep(TimeSpan.FromSeconds(2));

    return 42;
}

运转结果如下,可知Task 1Task 2均是运行在主线程上,并不是线程池线程。

云顶娱乐yd2221 13

SHA1Helper(对字符串实行SHA1卡塔尔:

故此要给泛型Generic的属性Name赋值,就须求赋值字符串类型的值。

参照书籍

正文主要参照了以下几本书,在那对那几个笔者表示由衷的感激涕零,多谢您们为.Net的恢弘所做的进献!

  1. 《CLR via C#》
  2. 《C# in Depth Third Edition》
  3. 《Essential C# 6.0》
  4. 云顶娱乐yd2221,《Multithreading with C# Cookbook Second Edition》
  5. 《C#八线程编程实战》

源码下载点击链接 示范源码下载

云顶娱乐yd2221 14

云顶娱乐yd2221 15

目录

本来你也能够自个儿定义需求过滤的词汇,以竖线 ‘|’ 分割:

哪些是限量泛型的门类呢?

1.7 达成撤消选项

在TAP形式中,达成废除选项和事先的异步形式相仿,都以利用CancellationToken来落实,但是不一样的是Task构造函数同意传入三个CancellationToken,从而在职分实际运转以前撤消它。

示范代码如下所示。

static void Main(string[] args)
{
    var cts = new CancellationTokenSource();
    // new Task时  可以传入一个 CancellationToken对象  可以在线程创建时  变取消任务
    var longTask = new Task<int>(() => TaskMethod("Task 1", 10, cts.Token), cts.Token);
    WriteLine(longTask.Status);
    cts.Cancel();
    WriteLine(longTask.Status);
    WriteLine("第一个任务在运行前被取消.");

    // 同样的 可以通过CancellationToken对象 取消正在运行的任务
    cts = new CancellationTokenSource();
    longTask = new Task<int>(() => TaskMethod("Task 2", 10, cts.Token), cts.Token);
    longTask.Start();

    for (int i = 0; i < 5; i++)
    {
        Sleep(TimeSpan.FromSeconds(0.5));
        WriteLine(longTask.Status);
    }
    cts.Cancel();
    for (int i = 0; i < 5; i++)
    {
        Sleep(TimeSpan.FromSeconds(0.5));
        WriteLine(longTask.Status);
    }

    WriteLine($"这个任务已完成,结果为{longTask.Result}");

    ReadLine();
}

static int TaskMethod(string name, int seconds, CancellationToken token)
{
    WriteLine($"任务运行在{CurrentThread.ManagedThreadId}上. 是否为线程池线程:{CurrentThread.IsThreadPoolThread}");

    for (int i = 0; i < seconds; i++)
    {
        Sleep(TimeSpan.FromSeconds(1));
        if (token.IsCancellationRequested)
        {
            return -1;
        }
    }

    return 42 * seconds;
}

运行结果如下图所示,这里须求在意的是,假使是在职分实行早先撤销了任务,那么它的终极状态是Canceled。假如是在实践进程中撤废职务,那么它的情事是RanCompletion

云顶娱乐yd2221 16

github:

如此我们就拿走了笔者们想要的结果,要是想采纳泛型类里的函数,道理也相似,只必要用反射来调用就能够。

1.10 使用TaskScheduler配置职责实行

Task中,肩负职务调整是TaskScheduler对象,FCL提供了八个派生自TaskScheduler的类型:线程池职分调解器(Thread Pool Task Scheduler)一路上下文职责调治器(Synchronization Scheduler)。默许情状下全数应用程序都使用线程池任务调节器,可是在UI组件中,不使用线程池中的线程,防止跨线程更新UI,要求采用同步上下文职分调治器。能够由此进行TaskSchedulerFromCurrentSynchronizationContext()静态方法来赢得对联合上下文职分调解器的引用。

示范程序如下所示,为了延时伙同上下文职责调整器,我们本次利用WPF来创立项目。

MainWindow.xaml 代码如下所示。

<Window x:Class="Recipe9.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Recipe9"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TextBlock Name="ContentTextBlock" HorizontalAlignment="Left" Margin="44,134,0,0" VerticalAlignment="Top" Width="425" Height="40"/>
        <Button Content="Sync" HorizontalAlignment="Left" Margin="45,190,0,0" VerticalAlignment="Top" Width="75" Click="ButtonSync_Click"/>
        <Button Content="Async" HorizontalAlignment="Left" Margin="165,190,0,0" VerticalAlignment="Top" Width="75" Click="ButtonAsync_Click"/>
        <Button Content="Async OK" HorizontalAlignment="Left" Margin="285,190,0,0" VerticalAlignment="Top" Width="75" Click="ButtonAsyncOK_Click"/>
    </Grid>
</Window>

MainWindow.xaml.cs 代码如下所示。

/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    // 同步执行 计算密集任务 导致UI线程阻塞
    private void ButtonSync_Click(object sender, RoutedEventArgs e)
    {
        ContentTextBlock.Text = string.Empty;

        try
        {
            string result = TaskMethod().Result;
            ContentTextBlock.Text = result;
        }
        catch (Exception ex)
        {
            ContentTextBlock.Text = ex.InnerException.Message;
        }
    }

    // 异步的方式来执行 计算密集任务 UI线程不会阻塞 但是 不能跨线程更新UI 所以会有异常
    private void ButtonAsync_Click(object sender, RoutedEventArgs e)
    {
        ContentTextBlock.Text = string.Empty;
        Mouse.OverrideCursor = Cursors.Wait;

        Task<string> task = TaskMethod();
        task.ContinueWith(t => {
            ContentTextBlock.Text = t.Exception.InnerException.Message;
            Mouse.OverrideCursor = null;
        }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.FromCurrentSynchronizationContext());
    }

    // 通过 异步 和 FromCurrentSynchronizationContext方法 创建了线程同步的上下文  没有跨线程更新UI 
    private void ButtonAsyncOK_Click(object sender, RoutedEventArgs e)
    {
        ContentTextBlock.Text = string.Empty;
        Mouse.OverrideCursor = Cursors.Wait;
        Task<string> task = TaskMethod(TaskScheduler.FromCurrentSynchronizationContext());

        task.ContinueWith(t => Mouse.OverrideCursor = null,
            CancellationToken.None,
            TaskContinuationOptions.None,
            TaskScheduler.FromCurrentSynchronizationContext());
    }

    Task<string> TaskMethod()
    {
        return TaskMethod(TaskScheduler.Default);
    }

    Task<string> TaskMethod(TaskScheduler scheduler)
    {
        Task delay = Task.Delay(TimeSpan.FromSeconds(5));

        return delay.ContinueWith(t =>
        {
            string str = $"任务运行在{CurrentThread.ManagedThreadId}上. 是否为线程池线程:{CurrentThread.IsThreadPoolThread}";

            Console.WriteLine(str);

            ContentTextBlock.Text = str;
            return str;
        }, scheduler);
    }
}

运营结果如下所示,从左至右依次单击按键,前五个开关将会掀起那二个。
云顶娱乐yd2221 17

切实消息如下所示。

云顶娱乐yd2221 18

加密:

有这么主张的校友,心里斟酌就好了,要是对老手那样说,他必定会内心默默的微笑,然后对您说,你想的没有错。

1.4 组合职分

在本节中,呈现了任务之中多个强有力的功能,那正是整合职责。通过整合职责可很好的陈述职责与职分之间的异步、同步关系,大大减弱了编程的难度。

整合职责重大是经过task.ContinueWith()task.WhenAny()task.WhenAll()等和task.GetAwaiter().OnCompleted()方法来完毕。

在使用task.ContinueWith()措施时,须求介意它也可传递一四种的枚举选项TaskContinuationOptions,该枚举选项和TaskCreationOptions相符,其切实定义如下表所示。

成员名称 说明
AttachedToParent 如果延续为子任务,则指定将延续附加到任务层次结构中的父级。 只有当延续前面的任务也是子任务时,延续才可以是子任务。 默认情况下,子任务(即由外部任务创建的内部任务)将独立于其父任务执行。 可以使用 TaskContinuationOptions.AttachedToParent 选项以便将父任务和子任务同步。请注意,如果使用 DenyChildAttach 选项配置父任务,则子任务中的 AttachedToParent 选项不起作用,并且子任务将作为分离的子任务执行。有关更多信息,请参见Attached and Detached Child Tasks
DenyChildAttach 指定任何使用 TaskCreationOptions.AttachedToParent 选项创建,并尝试作为附加的子任务执行的子任务(即,由此延续创建的任何嵌套内部任务)都无法附加到父任务,会改成作为分离的子任务执行。 有关详细信息,请参阅附加和分离的子任务
ExecuteSynchronously 指定应同步执行延续任务。 指定此选项后,延续任务在导致前面的任务转换为其最终状态的相同线程上运行。如果在创建延续任务时已经完成前面的任务,则延续任务将在创建此延续任务的线程上运行。 如果前面任务的 CancellationTokenSource 已在一个 finally(在 Visual Basic 中为 Finally)块中释放,则使用此选项的延续任务将在该 finally 块中运行。 只应同步执行运行时间非常短的延续任务。由于任务以同步方式执行,因此无需调用诸如 Task.Wait 的方法来确保调用线程等待任务完成。
HideScheduler 指定由延续通过调用方法(如 Task.RunTask.ContinueWith)创建的任务将默认计划程序 (TaskScheduler.Default) 视为当前的计划程序,而不是正在运行该延续的计划程序。
LazyCancellation 在延续取消的情况下,防止延续的完成直到完成先前的任务。
LongRunning 指定延续将是长期运行的、粗粒度的操作。 它会向 TaskScheduler 提示,过度订阅可能是合理的。
None 如果未指定延续选项,应在执行延续任务时使用指定的默认行为。 延续任务在前面的任务完成后以异步方式运行,与前面任务最终的 Task.Status 属性值无关。 如果延续为子任务,则会将其创建为分离的嵌套任务。
NotOnCanceled 指定不应在延续任务前面的任务已取消的情况下安排延续任务。 如果前面任务完成的 Task.Status 属性是 TaskStatus.Canceled,则前面的任务会取消。 此选项对多任务延续无效。
NotOnFaulted 指定不应在延续任务前面的任务引发了未处理异常的情况下安排延续任务。 如果前面任务完成的 Task.Status 属性是 TaskStatus.Faulted,则前面的任务会引发未处理的异常。 此选项对多任务延续无效。
NotOnRanToCompletion 指定不应在延续任务前面的任务已完成运行的情况下安排延续任务。 如果前面任务完成的 Task.Status 属性是 TaskStatus.RanToCompletion,则前面的任务会运行直至完成。 此选项对多任务延续无效。
OnlyOnCanceled 指定只应在延续前面的任务已取消的情况下安排延续任务。 如果前面任务完成的 Task.Status 属性是 TaskStatus.Canceled,则前面的任务会取消。 此选项对多任务延续无效。
OnlyOnFaulted 指定只有在延续任务前面的任务引发了未处理异常的情况下才应安排延续任务。 如果前面任务完成的 Task.Status 属性是 TaskStatus.Faulted,则前面的任务会引发未处理的异常。OnlyOnFaulted 选项可保证前面任务中的 Task.Exception 属性不是 null。 你可以使用该属性来捕获异常,并确定导致任务出错的异常。 如果你不访问 Exception 属性,则不会处理异常。 此外,如果尝试访问已取消或出错的任务的 Result 属性,则会引发一个新异常。此选项对多任务延续无效。
OnlyOnRanToCompletion 指定只应在延续任务前面的任务已完成运行的情况下才安排延续任务。 如果前面任务完成的 Task.Status 属性是 TaskStatus.RanToCompletion,则前面的任务会运行直至完成。 此选项对多任务延续无效。
PreferFairness 提示 TaskScheduler 按任务计划的顺序安排任务,因此较早安排的任务将更可能较早运行,而较晚安排运行的任务将更可能较晚运行。
RunContinuationsAsynchronously 指定应异步运行延续任务。 此选项优先于 TaskContinuationOptions.ExecuteSynchronously。

演示代码如下所示,使用ContinueWith()OnCompleted()办法结合了任务来运作,搭配分裂的TaskCreationOptionsTaskContinuationOptions来实现不一样的机能。

static void Main(string[] args)
{
    WriteLine($"主线程 线程 Id {CurrentThread.ManagedThreadId}");

    // 创建两个任务
    var firstTask = new Task<int>(() => TaskMethod("Frist Task",3));
    var secondTask = new Task<int>(()=> TaskMethod("Second Task",2));

    // 在默认的情况下 ContiueWith会在前面任务运行后再运行
    firstTask.ContinueWith(t => WriteLine($"第一次运行答案是 {t.Result}. 线程Id {CurrentThread.ManagedThreadId}. 是否为线程池线程: {CurrentThread.IsThreadPoolThread}"));

    // 启动任务
    firstTask.Start();
    secondTask.Start();

    Sleep(TimeSpan.FromSeconds(4));

    // 这里会紧接着 Second Task运行后运行, 但是由于添加了 OnlyOnRanToCompletion 和 ExecuteSynchronously 所以会由运行SecondTask的线程来 运行这个任务
    Task continuation = secondTask.ContinueWith(t => WriteLine($"第二次运行的答案是 {t.Result}. 线程Id {CurrentThread.ManagedThreadId}. 是否为线程池线程:{CurrentThread.IsThreadPoolThread}"),TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously);

    // OnCompleted 是一个事件  当contiuation运行完成后 执行OnCompleted Action事件
    continuation.GetAwaiter().OnCompleted(() => WriteLine($"后继任务完成. 线程Id {CurrentThread.ManagedThreadId}. 是否为线程池线程 {CurrentThread.IsThreadPoolThread}"));

    Sleep(TimeSpan.FromSeconds(2));
    WriteLine();

    firstTask = new Task<int>(() => 
    {
        // 使用了TaskCreationOptions.AttachedToParent 将这个Task和父Task关联, 当这个Task没有结束时  父Task 状态为 WaitingForChildrenToComplete
        var innerTask = Task.Factory.StartNew(() => TaskMethod("Second Task",5), TaskCreationOptions.AttachedToParent);

        innerTask.ContinueWith(t => TaskMethod("Thrid Task", 2), TaskContinuationOptions.AttachedToParent);

        return TaskMethod("First Task",2);
    });

    firstTask.Start();

    // 检查firstTask线程状态  根据上面的分析 首先是  Running -> WatingForChildrenToComplete -> RanToCompletion
    while (! firstTask.IsCompleted)
    {
        WriteLine(firstTask.Status);

        Sleep(TimeSpan.FromSeconds(0.5));
    }

    WriteLine(firstTask.Status);

    Console.ReadLine();
}

static int TaskMethod(string name, int seconds)
{
    WriteLine($"任务 {name} 正在运行,线程池线程 Id {CurrentThread.ManagedThreadId},是否为线程池线程: {CurrentThread.IsThreadPoolThread}");

    Sleep(TimeSpan.FromSeconds(seconds));

    return 42 * seconds;
}

运行结果如下图所示,与预期结果意气风发致。在这之中使用了task.Status来打字与印刷职责局维的场馆,对于task.Status的景色具体意思如下表所示。

成员名称 说明
Canceled 该任务已通过对其自身的 CancellationToken 引发 OperationCanceledException 对取消进行了确认,此时该标记处于已发送信号状态;或者在该任务开始执行之前,已向该任务的 CancellationToken 发出了信号。 有关详细信息,请参阅任务取消
Created 该任务已初始化,但尚未被计划。
Faulted 由于未处理异常的原因而完成的任务。
RanToCompletion 已成功完成执行的任务。
Running 该任务正在运行,但尚未完成。
WaitingForActivation 该任务正在等待 .NET Framework 基础结构在内部将其激活并进行计划。
WaitingForChildrenToComplete 该任务已完成执行,正在隐式等待附加的子任务完成。
WaitingToRun 该任务已被计划执行,但尚未开始执行。

云顶娱乐yd2221 19

 

下边代码定义了一个Int类型的泛型Generic。

本种类首页链接:[C#多线程编制程序种类(生机勃勃卡塔尔国- 简要介绍 ]

理所必然为了安全起见,你能够自定义本身的 十柒位依然叁11位key  和十八人的iv:

在泛型类中,有个特别的束缚可供我们应用。

1.2 创造职责

在本节中,首若是以身作则了什么样创设三个义务。其重点利用了System.Threading.Tasks取名空间下的Task类。该类能够被实例化并且提供了生龙活虎组静态方法,可以方便快捷的开创义务。

在底下实例代码中,分别延时了二种广泛的职分成立形式,并且创建使命是足以钦点职务成立的选项,进而到达最优的创制格局。

TaskCreationOptions中计算有7个枚举,枚举是可以应用|运算符组合定义的。其枚举如下表所示。

成员名称 说明
AttachedToParent 指定将任务附加到任务层次结构中的某个父级。 默认情况下,子任务(即由外部任务创建的内部任务)将独立于其父任务执行。 可以使用 TaskContinuationOptions.AttachedToParent 选项以便将父任务和子任务同步。请注意,如果使用 DenyChildAttach 选项配置父任务,则子任务中的 AttachedToParent 选项不起作用,并且子任务将作为分离的子任务执行。有关详细信息,请参阅附加和分离的子任务
DenyChildAttach 指定任何尝试作为附加的子任务执行(即,使用 AttachedToParent 选项创建)的子任务都无法附加到父任务,会改成作为分离的子任务执行。 有关详细信息,请参阅附加和分离的子任务
HideScheduler 防止环境计划程序被视为已创建任务的当前计划程序。 这意味着像 StartNew 或 ContinueWith 创建任务的执行操作将被视为 Default 当前计划程序。
LongRunning 指定任务将是长时间运行的、粗粒度的操作,涉及比细化的系统更少、更大的组件。 它会向 TaskScheduler 提示,过度订阅可能是合理的。 可以通过过度订阅创建比可用硬件线程数更多的线程。 它还将提示任务计划程序:该任务需要附加线程,以使任务不阻塞本地线程池队列中其他线程或工作项的向前推动。
None 指定应使用默认行为。
PreferFairness 提示 TaskScheduler 以一种尽可能公平的方式安排任务,这意味着较早安排的任务将更可能较早运行,而较晚安排运行的任务将更可能较晚运行。
RunContinuationsAsynchronously 强制异步执行添加到当前任务的延续任务。请注意,RunContinuationsAsynchronously 成员在以 .NET Framework 4.6 开头的 TaskCreationOptions 枚举中可用。
static void Main(string[] args)
{
    // 使用构造方法创建任务
    var t1 = new Task(() => TaskMethod("Task 1"));
    var t2 = new Task(() => TaskMethod("Task 2"));

    // 需要手动启动
    t2.Start();
    t1.Start();

    // 使用Task.Run 方法启动任务  不需要手动启动
    Task.Run(() => TaskMethod("Task 3"));

    // 使用 Task.Factory.StartNew方法 启动任务 实际上就是Task.Run
    Task.Factory.StartNew(() => TaskMethod("Task 4"));

    // 在StartNew的基础上 添加 TaskCreationOptions.LongRunning 告诉 Factory该任务需要长时间运行
    // 那么它就会可能会创建一个 非线程池线程来执行任务  
    Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);

    ReadLine();
}

static void TaskMethod(string name)
{
    WriteLine($"任务 {name} 运行,线程 id {CurrentThread.ManagedThreadId}. 是否为线程池线程: {CurrentThread.IsThreadPoolThread}.");
}

运转结果如下图所示。

云顶娱乐yd2221 20

云顶娱乐yd2221 21

它的界定是,必要大家内定的类型T必得是Base,大概该品种世襲自Base,如FanXing类。

本文由云顶娱乐yd2221发布,转载请注明来源:享受二个赞助类,八十四线程编制程序连串云顶