1、Task的优势

  ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便。比如:
  ◆ ThreadPool不支持线程的取消、完成、失败通知等交互性操作;
  ◆ ThreadPool不支持线程执行的先后次序;
  以往,如果开发者要实现上述功能,需要完成很多额外的工作,现在,FCL中提供了一个功能更强大的概念:Task。Task在线程池的基础上进行了优化,并提供了更多的API。在FCL4.0中,如果我们要编写多线程程序,Task显然已经优于传统的方式。
  以下是一个简单的任务示例:

using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Task t = new Task(() =>
{
Console.WriteLine("任务开始工作……");
//模拟工作过程
Thread.Sleep();
});
t.Start();
t.ContinueWith((task) =>
{
Console.WriteLine("任务完成,完成时候的状态为:");
Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}", task.IsCanceled, task.IsCompleted, task.IsFaulted);
});
Console.ReadKey();
}
}
}

2、Task的用法

  2.1、创建任务

  (一)无返回值的方式
  方式1:

  var t1 = new Task(() => TaskMethod("Task 1"));
  t1.Start();
  Task.WaitAll(t1);//等待所有任务结束
  注:任务的状态:
  Start之前为:Created
  Start之后为:WaitingToRun

  方式2:

  Task.Run(() => TaskMethod("Task 2"));

  方式3:

  Task.Factory.StartNew(() => TaskMethod("Task 3")); 直接异步的方法
  //或者
  var t3=Task.Factory.StartNew(() => TaskMethod("Task 3"));
  Task.WaitAll(t3);//等待所有任务结束
  //任务的状态:
  Start之前为:Running
  Start之后为:Running
using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var t1 = new Task(() => TaskMethod("Task 1"));
var t2 = new Task(() => TaskMethod("Task 2"));
t2.Start();
t1.Start();
Task.WaitAll(t1, t2);
Task.Run(() => TaskMethod("Task 3"));
Task.Factory.StartNew(() => TaskMethod("Task 4"));
//标记为长时间运行任务,则任务不会使用线程池,而在单独的线程中运行。
Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning); #region 常规的使用方式
Console.WriteLine("主线程执行业务处理.");
//创建任务
Task task = new Task(() =>
{
Console.WriteLine("使用System.Threading.Tasks.Task执行异步操作.");
for (int i = ; i < ; i++)
{
Console.WriteLine(i);
}
});
//启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)
task.Start();
Console.WriteLine("主线程执行其他处理");
task.Wait();
#endregion Thread.Sleep(TimeSpan.FromSeconds());
Console.ReadLine();
} static void TaskMethod(string name)
{
Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
}
}
}

  async/await的实现方式:

using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
async static void AsyncFunction()
{
await Task.Delay();
Console.WriteLine("使用System.Threading.Tasks.Task执行异步操作.");
for (int i = ; i < ; i++)
{
Console.WriteLine(string.Format("AsyncFunction:i={0}", i));
}
} public static void Main()
{
Console.WriteLine("主线程执行业务处理.");
AsyncFunction();
Console.WriteLine("主线程执行其他处理");
for (int i = ; i < ; i++)
{
Console.WriteLine(string.Format("Main:i={0}", i));
}
Console.ReadLine();
}
}
}

  (二)带返回值的方式
  方式4:

  Task<int> task = CreateTask("Task 1");
  task.Start();
  int result = task.Result;
using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
static Task<int> CreateTask(string name)
{
return new Task<int>(() => TaskMethod(name));
} static void Main(string[] args)
{
TaskMethod("Main Thread Task");
Task<int> task = CreateTask("Task 1");
task.Start();
int result = task.Result;
Console.WriteLine("Task 1 Result is: {0}", result); task = CreateTask("Task 2");
//该任务会运行在主线程中
task.RunSynchronously();
result = task.Result;
Console.WriteLine("Task 2 Result is: {0}", result); task = CreateTask("Task 3");
Console.WriteLine(task.Status);
task.Start(); while (!task.IsCompleted)
{
Console.WriteLine(task.Status);
Thread.Sleep(TimeSpan.FromSeconds(0.5));
} Console.WriteLine(task.Status);
result = task.Result;
Console.WriteLine("Task 3 Result is: {0}", result); #region 常规使用方式
//创建任务
Task<int> getsumtask = new Task<int>(() => Getsum());
//启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)
getsumtask.Start();
Console.WriteLine("主线程执行其他处理");
//等待任务的完成执行过程。
getsumtask.Wait();
//获得任务的执行结果
Console.WriteLine("任务执行结果:{0}", getsumtask.Result.ToString());
#endregion
} static int TaskMethod(string name)
{
Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds());
return ;
} static int Getsum()
{
int sum = ;
Console.WriteLine("使用Task执行异步操作.");
for (int i = ; i < ; i++)
{
sum += i;
}
return sum;
}
}
}

async/await的实现:

using System;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
public static void Main()
{
var ret1 = AsyncGetsum();
Console.WriteLine("主线程执行其他处理");
for (int i = ; i <= ; i++)
Console.WriteLine("Call Main()");
int result = ret1.Result; //阻塞主线程
Console.WriteLine("任务执行结果:{0}", result);
} async static Task<int> AsyncGetsum()
{
await Task.Delay();
int sum = ;
Console.WriteLine("使用Task执行异步操作.");
for (int i = ; i < ; i++)
{
sum += i;
}
return sum;
}
}
}

  2.2、组合任务.ContinueWith

   简单Demo:

using System;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
public static void Main()
{
//创建一个任务
Task<int> task = new Task<int>(() =>
{
int sum = ;
Console.WriteLine("使用Task执行异步操作.");
for (int i = ; i < ; i++)
{
sum += i;
}
return sum;
});
//启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)
task.Start();
Console.WriteLine("主线程执行其他处理");
//任务完成时执行处理。
Task cwt = task.ContinueWith(t =>
{
Console.WriteLine("任务完成后的执行结果:{0}", t.Result.ToString());
});
task.Wait();
cwt.Wait();
}
}
}

   任务的串行:

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
ConcurrentStack<int> stack = new ConcurrentStack<int>(); //t1先串行
var t1 = Task.Factory.StartNew(() =>
{
stack.Push();
stack.Push();
}); //t2,t3并行执行
var t2 = t1.ContinueWith(t =>
{
int result;
stack.TryPop(out result);
Console.WriteLine("Task t2 result={0},Thread id {1}", result, Thread.CurrentThread.ManagedThreadId);
}); //t2,t3并行执行
var t3 = t1.ContinueWith(t =>
{
int result;
stack.TryPop(out result);
Console.WriteLine("Task t3 result={0},Thread id {1}", result, Thread.CurrentThread.ManagedThreadId);
}); //等待t2和t3执行完
Task.WaitAll(t2, t3); //t7串行执行
var t4 = Task.Factory.StartNew(() =>
{
Console.WriteLine("当前集合元素个数:{0},Thread id {1}", stack.Count, Thread.CurrentThread.ManagedThreadId);
});
t4.Wait();
}
}
}

  子任务:

using System;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
public static void Main()
{
Task<string[]> parent = new Task<string[]>(state =>
{
Console.WriteLine(state);
string[] result = new string[];
//创建并启动子任务
new Task(() => { result[] = "我是子任务1。"; }, TaskCreationOptions.AttachedToParent).Start();
new Task(() => { result[] = "我是子任务2。"; }, TaskCreationOptions.AttachedToParent).Start();
return result;
}, "我是父任务,并在我的处理过程中创建多个子任务,所有子任务完成以后我才会结束执行。");
//任务处理完成后执行的操作
parent.ContinueWith(t =>
{
Array.ForEach(t.Result, r => Console.WriteLine(r));
});
//启动父任务
parent.Start();
//等待任务结束 Wait只能等待父线程结束,没办法等到父线程的ContinueWith结束
//parent.Wait();
Console.ReadLine(); }
}
}

  动态并行(TaskCreationOptions.AttachedToParent) 父任务等待所有子任务完成后 整个任务才算完成

using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Node
{
public Node Left { get; set; }
public Node Right { get; set; }
public string Text { get; set; }
} class Program
{
static Node GetNode()
{
Node root = new Node
{
Left = new Node
{
Left = new Node
{
Text = "L-L"
},
Right = new Node
{
Text = "L-R"
},
Text = "L"
},
Right = new Node
{
Left = new Node
{
Text = "R-L"
},
Right = new Node
{
Text = "R-R"
},
Text = "R"
},
Text = "Root"
};
return root;
} static void Main(string[] args)
{
Node root = GetNode();
DisplayTree(root);
} static void DisplayTree(Node root)
{
var task = Task.Factory.StartNew(() => DisplayNode(root),
CancellationToken.None,
TaskCreationOptions.None,
TaskScheduler.Default);
task.Wait();
} static void DisplayNode(Node current)
{ if (current.Left != null)
Task.Factory.StartNew(() => DisplayNode(current.Left),
CancellationToken.None,
TaskCreationOptions.AttachedToParent,
TaskScheduler.Default);
if (current.Right != null)
Task.Factory.StartNew(() => DisplayNode(current.Right),
CancellationToken.None,
TaskCreationOptions.AttachedToParent,
TaskScheduler.Default);
Console.WriteLine("当前节点的值为{0};处理的ThreadId={1}", current.Text, Thread.CurrentThread.ManagedThreadId);
}
}
}

  2.3、取消任务 CancellationTokenSource

using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
private static int TaskMethod(string name, int seconds, CancellationToken token)
{
Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
for (int i = ; i < seconds; i++)
{
Thread.Sleep(TimeSpan.FromSeconds());
if (token.IsCancellationRequested) return -;
}
return * seconds;
} private static void Main(string[] args)
{
var cts = new CancellationTokenSource();
var longTask = new Task<int>(() => TaskMethod("Task 1", , cts.Token), cts.Token);
Console.WriteLine(longTask.Status);
cts.Cancel();
Console.WriteLine(longTask.Status);
Console.WriteLine("First task has been cancelled before execution");
cts = new CancellationTokenSource();
longTask = new Task<int>(() => TaskMethod("Task 2", , cts.Token), cts.Token);
longTask.Start();
for (int i = ; i < ; i++)
{
Thread.Sleep(TimeSpan.FromSeconds(0.5));
Console.WriteLine(longTask.Status);
}
cts.Cancel();
for (int i = ; i < ; i++)
{
Thread.Sleep(TimeSpan.FromSeconds(0.5));
Console.WriteLine(longTask.Status);
} Console.WriteLine("A task has been completed with result {0}.", longTask.Result);
}
}
}

  2.4、处理任务中的异常

  单个任务:

using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
static int TaskMethod(string name, int seconds)
{
Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds(seconds));
throw new Exception("Boom!");
return * seconds;
} static void Main(string[] args)
{
try
{
Task<int> task = Task.Run(() => TaskMethod("Task 2", ));
int result = task.GetAwaiter().GetResult();
Console.WriteLine("Result: {0}", result);
}
catch (Exception ex)
{
Console.WriteLine("Task 2 Exception caught: {0}", ex.Message);
}
Console.WriteLine("----------------------------------------------");
Console.WriteLine();
}
}
}

  多个任务:

using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
static int TaskMethod(string name, int seconds)
{
Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds(seconds));
throw new Exception(string.Format("Task {0} Boom!", name));
return * seconds;
} public static void Main(string[] args)
{
try
{
var t1 = new Task<int>(() => TaskMethod("Task 3", ));
var t2 = new Task<int>(() => TaskMethod("Task 4", ));
var complexTask = Task.WhenAll(t1, t2);
var exceptionHandler = complexTask.ContinueWith(t =>
Console.WriteLine("Result: {0}", t.Result),
TaskContinuationOptions.OnlyOnFaulted
);
t1.Start();
t2.Start();
Task.WaitAll(t1, t2);
}
catch (AggregateException ex)
{
ex.Handle(exception =>
{
Console.WriteLine(exception.Message);
return true;
});
}
}
}
}

async/await的方式:

using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
static async Task ThrowNotImplementedExceptionAsync()
{
throw new NotImplementedException();
} static async Task ThrowInvalidOperationExceptionAsync()
{
throw new InvalidOperationException();
} static async Task Normal()
{
await Fun();
} static Task Fun()
{
return Task.Run(() =>
{
for (int i = ; i <= ; i++)
{
Console.WriteLine("i={0}", i);
Thread.Sleep();
}
});
} static async Task ObserveOneExceptionAsync()
{
var task1 = ThrowNotImplementedExceptionAsync();
var task2 = ThrowInvalidOperationExceptionAsync();
var task3 = Normal(); try
{
//异步的方式
Task allTasks = Task.WhenAll(task1, task2, task3);
await allTasks;
//同步的方式
//Task.WaitAll(task1, task2, task3);
}
catch (NotImplementedException ex)
{
Console.WriteLine("task1 任务报错!");
}
catch (InvalidOperationException ex)
{
Console.WriteLine("task2 任务报错!");
}
catch (Exception ex)
{
Console.WriteLine("任务报错!");
} } public static void Main()
{
Task task = ObserveOneExceptionAsync();
Console.WriteLine("主线程继续运行........");
task.Wait();
}
}
}

  2.5、Task.FromResult的应用

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
static IDictionary<string, string> cache = new Dictionary<string, string>()
{
{"","A"},
{"","B"},
{"","C"},
{"","D"},
{"","E"},
{"","F"},
}; public static void Main()
{
Task<string> task = GetValueFromCache("");
Console.WriteLine("主程序继续执行。。。。");
string result = task.Result;
Console.WriteLine("result={0}", result); } private static Task<string> GetValueFromCache(string key)
{
Console.WriteLine("GetValueFromCache开始执行。。。。");
string result = string.Empty;
//Task.Delay(5000);
Thread.Sleep();
Console.WriteLine("GetValueFromCache继续执行。。。。");
if (cache.TryGetValue(key, out result))
{
return Task.FromResult(result);
}
return Task.FromResult("");
} }
}

  2.6、使用IProgress实现异步编程的进程通知

  IProgress<in T>只提供了一个方法void Report(T value),通过Report方法把一个T类型的值报告给IProgress,然后IProgress<in T>的实现类Progress<in T>的构造函数接收类型为Action<T>的形参,通过这个委托让进度显示在UI界面中。

using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
static void DoProcessing(IProgress<int> progress)
{
for (int i = ; i <= ; ++i)
{
Thread.Sleep();
if (progress != null)
{
progress.Report(i);
}
}
} static async Task Display()
{
//当前线程
var progress = new Progress<int>(percent =>
{
Console.Clear();
Console.Write("{0}%", percent);
});
//线程池线程
await Task.Run(() => DoProcessing(progress));
Console.WriteLine("");
Console.WriteLine("结束");
} public static void Main()
{
Task task = Display();
task.Wait();
}
}
}

  2.7、Factory.FromAsync的应用 (简APM模式(委托)转换为任务)(BeginXXX和EndXXX)

  带回调方式的

using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
private delegate string AsynchronousTask(string threadName); private static string Test(string threadName)
{
Console.WriteLine("Starting...");
Console.WriteLine("Is thread pool thread: {0}", Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds());
Thread.CurrentThread.Name = threadName;
return string.Format("Thread name: {0}", Thread.CurrentThread.Name);
} private static void Callback(IAsyncResult ar)
{
Console.WriteLine("Starting a callback...");
Console.WriteLine("State passed to a callbak: {0}", ar.AsyncState);
Console.WriteLine("Is thread pool thread: {0}", Thread.CurrentThread.IsThreadPoolThread);
Console.WriteLine("Thread pool worker thread id: {0}", Thread.CurrentThread.ManagedThreadId);
} //执行的流程是 先执行Test--->Callback--->task.ContinueWith
static void Main(string[] args)
{
AsynchronousTask d = Test;
Console.WriteLine("Option 1");
Task<string> task = Task<string>.Factory.FromAsync(
d.BeginInvoke("AsyncTaskThread", Callback, "a delegate asynchronous call"), d.EndInvoke); task.ContinueWith(t => Console.WriteLine("Callback is finished, now running a continuation! Result: {0}",
t.Result)); while (!task.IsCompleted)
{
Console.WriteLine(task.Status);
Thread.Sleep(TimeSpan.FromSeconds(0.5));
}
Console.WriteLine(task.Status); }
}
}

  不带回调方式的

using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
private delegate string AsynchronousTask(string threadName); private static string Test(string threadName)
{
Console.WriteLine("Starting...");
Console.WriteLine("Is thread pool thread: {0}", Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds());
Thread.CurrentThread.Name = threadName;
return string.Format("Thread name: {0}", Thread.CurrentThread.Name);
} //执行的流程是 先执行Test--->task.ContinueWith
static void Main(string[] args)
{
AsynchronousTask d = Test;
Task<string> task = Task<string>.Factory.FromAsync(
d.BeginInvoke, d.EndInvoke, "AsyncTaskThread", "a delegate asynchronous call");
task.ContinueWith(t => Console.WriteLine("Task is completed, now running a continuation! Result: {0}",
t.Result));
while (!task.IsCompleted)
{
Console.WriteLine(task.Status);
Thread.Sleep(TimeSpan.FromSeconds(0.5));
}
Console.WriteLine(task.Status); }
}
}

//Task启动带参数和返回值的函数任务
//下面的例子test2 是个带参数和返回值的函数。 private int test2(object i)
{
this.Invoke(new Action(() =>
{
pictureBox1.Visible = true;
}));
System.Threading.Thread.Sleep();
MessageBox.Show("hello:" + i);
this.Invoke(new Action(() =>
{
pictureBox1.Visible = false;
}));
return ;
} //测试调用
private void call()
{
//Func<string, string> funcOne = delegate(string s){ return "fff"; };
object i = ;
var t = Task<int>.Factory.StartNew(new Func<object, int>(test2), i);
} //= 下载网站源文件例子 == == == == == == == == == == == ==
//HttpClient 引用System.Net.Http
private async Task< int> test2(object i)
{
this.Invoke(new Action(() =>
{
pictureBox1.Visible = true;
})); HttpClient client = new HttpClient();
var a = await client.GetAsync("http://www.baidu.com");
Task<string> s = a.Content.ReadAsStringAsync();
MessageBox.Show (s.Result); //System.Threading.Thread.Sleep(3000);
//MessageBox.Show("hello:"+ i);
this.Invoke(new Action(() =>
{
pictureBox1.Visible = false;
}));
return ;
} async private void call()
{
//Func<string, string> funcOne = delegate(string s){ return "fff"; };
object i = ;
var t = Task<Task<int>>.Factory.StartNew(new Func<object, Task<int>>(test2), i);
} //----------或者---------- private async void test2()
{
this.Invoke(new Action(() =>
{
pictureBox1.Visible = true;
}));
HttpClient client = new HttpClient();
var a = await client.GetAsync("http://www.baidu.com");
Task<string> s = a.Content.ReadAsStringAsync();
MessageBox.Show (s.Result);
this.Invoke(new Action(() =>
{
pictureBox1.Visible = false;
}));
} private void call()
{
var t = Task.Run(new Action(test2));
//相当于
//Thread th= new Thread(new ThreadStart(test2));
//th.Start();
}

Task启动带参数和返回值的函数任务

C# Task详解的更多相关文章

  1. Gradle技术之四 - Gradle的Task详解

    1 Gradle的Task详解 1 Task定义和配置 2 Task的执行 3 Task的依赖和执行顺序 4 Task类型 5 Task结合gradle的生命周期 6 Task实战 1.1 Task定 ...

  2. Android Gradle 自定义Task 详解

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/76408024 本文出自[赵彦军的博客] 一:Gradle 是什么 Gradle是一 ...

  3. Activity的Task详解

    1.Task Task是一个具有栈结构(后进先出)的容器,可以放置多个Activity实例.启动一个应用,系统就会为之创建一个Task,来放置根Activity.默认情况下,一个Activity启动另 ...

  4. asyncio异步IO--协程(Coroutine)与任务(Task)详解

    摘要:本文翻译自Coroutines and Tasks,主要介绍asyncio中用于处理协程和任务的方法和接口.在翻译过程中,译者在官方文档的基础上增加了部分样例代码和示意图表,以帮助读者对文档的理 ...

  5. Gradle 使用教程之 Task 详解

    最近打算学习下 gradle 在 Android 中的使用,结果百度出来的文章都是介绍性文章,没啥干货.后来找到 gradle 官网教程,自己对着撸. Gradle 概述: Gradle 是一个基于 ...

  6. storm源码之理解Storm中Worker、Executor、Task关系 + 并发度详解

    本文导读: 1 Worker.Executor.task详解 2 配置拓扑的并发度 3 拓扑示例 4 动态配置拓扑并发度 Worker.Executor.Task详解: Storm在集群上运行一个To ...

  7. [Spark内核] 第36课:TaskScheduler内幕天机解密:Spark shell案例运行日志详解、TaskScheduler和SchedulerBackend、FIFO与FAIR、Task运行时本地性算法详解等

    本課主題 通过 Spark-shell 窥探程序运行时的状况 TaskScheduler 与 SchedulerBackend 之间的关系 FIFO 与 FAIR 两种调度模式彻底解密 Task 数据 ...

  8. 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程

    反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑)   背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...

  9. EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解

    前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...

随机推荐

  1. HDUOJ Number Sequence 题目1005

     /*Number Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  2. javascript下将字符类型转换成布尔值

    办不到!孙子,我告诉你,这办不到! 比如说, var sb = "false"; alert(!!sb);//结果显示true! 事前是想得很美的: sb == "fal ...

  3. java操作linux,调用shell命令

    import org.junit.jupiter.api.Test; import java.io.BufferedReader; import java.io.IOException; import ...

  4. HDU 5763Another Meaning

    Another Meaning Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  5. java连接Oracle案例

    首先来讲一下桥连接: 首先配置数据源:打开控制面板——管理工具——数据源(ODBC)——用户DSN——添加——找到Oracle驱动程序. //JDBC-ODBC桥连接public class Conn ...

  6. brew安装PHP7 swoole

    环境: 系统:mac os High Sierra 10.13.3 php版本:7.0.27_19 1.安装homebrew brew 又叫Homebrew,是Mac OSX上的软件包管理工具,能在M ...

  7. POJ1279 Art Gallery 多边形的核

    POJ1279 给一个多边形 求它的核的面积 所谓多边形的核 是多边形中的一个点集 满足其中的点与多边形边上的点的连线全部在多边形中 用多边形的每一条边所在的直线去切整个坐标平面 得到的一个凸包就是核 ...

  8. bzoj1776

    点分治/贪心 对于点分治的理解不够深刻...点分治能统计树上每个点对的信息,那么这里就是统计同种颜色点对之间的最大距离,自然可以用点分 然后点分,每次统计最大距离,但是略微卡常... 还有一种贪心的方 ...

  9. E20180115-hm

    auxiliary  adj. 辅助的; 备用的,补充的; 附加的; 副的;                n. 助动词; 辅助者,辅助人员; 附属机构,附属团体; 辅助设备;  departure  ...

  10. Linux 用户管理(2)

    Linux 用户管理2 添加修改和删除用户,必须是超级管理员root账号才可以进行的操作,所以当当前账号不是超级管理员root账号时,首先要先切换为root账号. 如图,ylq为普通用户,执行添加用户 ...