using System.Threading;
/// <summary>
/// 执行动作:耗时而已
/// </summary>
private void TestThread(string threadName)
{
Console.WriteLine("TestThread Start Name={2}当前线程的id:{0},当前时间为{1},",
System.Threading.Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"), threadName);
;
; i < ; i++)
{
sum += i;
}
//Thread.Sleep(1000);
Console.WriteLine("TestThread End Name={2}当前线程的id:{0},当前时间为{1},计算结果{3}",
System.Threading.Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"), threadName, sum);
}
TestThread
同步方法
private void btnSync_Click(object sender, EventArgs e)
{
Stopwatch watch = new Stopwatch();
watch.Start();
Console.WriteLine();
Console.WriteLine("*********************************btnSync_Click Start*********************************************");
Console.WriteLine("btnSync_Click当前主线程的id:{0}", Thread.CurrentThread.ManagedThreadId);
; i < ; i++)
{
string name = string.Format("btnSync_Click_{0}", i);
TestThread(name);
}
watch.Stop();
Console.WriteLine("*********************************btnSync_Click End {0}********************************************", watch.ElapsedMilliseconds);
Console.WriteLine();
}
异步调用
异步调用 同步方法会卡界面,异步多线程不会,原因:同步方法占用了UI线程,无法响应其他操作;异步多线程,UI线程不需要等待计算,计算由子线程完成 同步方法慢,只有主线程计算;异步方法快,启动了多个线程同时计算,会占用更多的资源(多线程的调度管理,也是需要消耗资源的) 异步方法的启动和执行时无序,原因:线程的申请是无序获取;不同线程同一个任务的执行速度也不一定相同;
1 Stopwatch watch = new Stopwatch();
watch.Start();
Console.WriteLine();
Console.WriteLine("*********************************btnAsync_Click Start*********************************************");
Console.WriteLine("btnAsync_Click当前主线程的id:{0}", Thread.CurrentThread.ManagedThreadId);
List<IAsyncResult> asyncResultList = new List<IAsyncResult>();
; i < ; i++)
{
string name = string.Format("btnSync_Click_{0}", i);
Action<string> act = TestThread;
//act.Invoke(name);
asyncResultList.Add(act.BeginInvoke(name, null, null));
//Thread.Sleep(1);
}
watch.Stop();
Console.WriteLine("*********************************btnAsync_Click End {0}********************************************", watch.ElapsedMilliseconds);
Console.WriteLine();
等待:
foreach (var item in asyncResultList)
{
item.AsyncWaitHandle.WaitOne();
}
或者
)
{
Thread.Sleep();//主线程等待着
}
共有资源的访问
; private static object IntValueLock = new object();
; i < ; i++)
{
IntValue++;
}
Action act = () =>
{
lock (IntValueLock)
{
IntValue++;
Console.WriteLine(IntValue.ToString());
}
};
; i < ; i++)
{
act.BeginInvoke(null, null);
}
多线程 Thread
Stopwatch watch = new Stopwatch();
watch.Start();
Console.WriteLine();
Console.WriteLine("*********************************btnThreads_Click Start*********************************************");
Console.WriteLine("btnThreads_Click当前主线程的id:{0}", Thread.CurrentThread.ManagedThreadId);
//表示在 System.Threading.Thread 上执行的方法。 包含该线程过程的数据的对象。
ParameterizedThreadStart method = t => TestThread(t.ToString());
List<Thread> threadList = new List<Thread>();
; i < ; i++)
{
string name = string.Format("btnSync_Click_{0}", i);
Thread thread = new Thread(method);//默认是前台线程,进程取消后,还会完成计算任务
//thread.IsBackground = true;//设置成后台线程,进程取消后,立即结束
thread.Start(name);
threadList.Add(thread);
}
)
{
Thread.Sleep();//主线程等待
Console.WriteLine("btnThreads_Click当前主线程的id:{0}", Thread.CurrentThread.ManagedThreadId);
}
//foreach (var thread in threadList)
//{
// thread.Join();//阻塞调用线程,直到某个线程终止为止。
//}
watch.Stop();
Console.WriteLine("*********************************btnThreads_Click End {0}********************************************", watch.ElapsedMilliseconds);
Console.WriteLine();
对比委托的beginInvoke的回调,Thread怎么有回调呢?而且IAsyncResult可以获取其结果
// 摘要:
// 表示异步操作的状态。
[ComVisible(true)]
public interface IAsyncResult
{
// 摘要:
// 获取用户定义的对象,它限定或包含关于异步操作的信息。
//
// 返回结果:
// 用户定义的对象,它限定或包含关于异步操作的信息。
object AsyncState { get; }
//
// 摘要:
// 获取用于等待异步操作完成的 System.Threading.WaitHandle。
//
// 返回结果:
// 用于等待异步操作完成的 System.Threading.WaitHandle。
WaitHandle AsyncWaitHandle { get; }
//
// 摘要:
// 获取一个值,该值指示异步操作是否同步完成。
//
// 返回结果:
// 如果异步操作同步完成,则为 true;否则为 false。
bool CompletedSynchronously { get; }
//
// 摘要:
// 获取一个值,该值指示异步操作是否已完成。
//
// 返回结果:
// 如果操作完成则为 true,否则为 false。
bool IsCompleted { get; }
IAsyncResult
不带返回值
/// <summary>
/// 带回掉和返回值的线程写法
/// </summary>
/// <param name="func">执行方法-带参数</param>
/// <param name="callback">回调</param>
/// <returns></returns>
private string ThreadWithCallback(Func<string> func, Action callback)
{
string result = null;
ThreadStart method = new ThreadStart(
() =>
{
result = func();
callback();
});
Thread thread = new Thread(method);
thread.Start();
thread.Join();//等待线程完成
return result;
}
带返回值
/// <summary>
/// 带回掉和返回值的线程写法
/// </summary>
/// <param name="func">执行方法-带参数</param>
/// <param name="callback">回调</param>
/// <returns></returns>
private string ThreadWithCallback(Func<string> func, Action callback)
{
string result = null;
ThreadStart method = new ThreadStart(
() =>
{
result = func();
callback();
});
Thread thread = new Thread(method);
thread.Start();
thread.Join();//等待线程完成
return result;
}
线程池ThreadPool
Stopwatch watch = new Stopwatch();
watch.Start();
Console.WriteLine();
Console.WriteLine("*********************************btnThreadPool_Click Start*********************************************");
Console.WriteLine("btnThreadPool_Click当前主线程的id:{0}", Thread.CurrentThread.ManagedThreadId);
; i < ; i++)
{
string name = string.Format("btnThreadPool_Click{0}", i);
//表示线程池线程要执行的方法
WaitCallback act = t => TestThread(t.ToString());
//将方法排入队列以便执行,并指定包含该方法所用数据的对象。 此方法在有线程池线程变得可用时执行。
//System.Threading.WaitCallback,它表示要执行的方法。
ThreadPool.QueueUserWorkItem(act, name);
}
watch.Stop();
Console.WriteLine("*********************************btnThreadPool_Click End {0}********************************************", watch.ElapsedMilliseconds);
Console.WriteLine();
可以设置数目,这是Thread没有的
ThreadPool.SetMaxThreads(, );//最小也是核数
ThreadPool.SetMinThreads(, );
int workerThreads;
int ioThreads;
//-----------------------工作线程 和 IO线程
ThreadPool.GetMaxThreads(out workerThreads, out ioThreads);
Console.WriteLine(String.Format("Max worker threads: {0}; Max I/O threads: {1}", workerThreads, ioThreads));
ThreadPool.GetMinThreads(out workerThreads, out ioThreads);
Console.WriteLine(String.Format("Min worker threads: {0}; Min I/O threads: {1}", workerThreads, ioThreads));
ThreadPool.GetAvailableThreads(out workerThreads, out ioThreads);
Console.WriteLine(String.Format("Available worker threads: {0}; Available I/O threads: {1}", workerThreads, ioThreads));
信号量--线程安全
// 摘要:
// 通知一个或多个正在等待的线程已发生事件。 此类不能被继承。
[ComVisible(true)]
public sealed class ManualResetEvent : EventWaitHandle
{
// 摘要:
// 用一个指示是否将初始状态设置为终止的布尔值初始化 System.Threading.ManualResetEvent 类的新实例。
//
// 参数:
// initialState:
// 如果为 true,则将初始状态设置为终止;如果为 false,则将初始状态设置为非终止。
public ManualResetEvent(bool initialState);
}
ManualResetEvent
//如果为 true,则将初始状态设置为终止;如果为 false,则将初始状态设置为非终止
ManualResetEvent test = new ManualResetEvent(false);
new Action(() =>
{
Thread.Sleep();
test.Set();
}).BeginInvoke(null, null);
test.WaitOne();//是无法通过的----非终止状态--线程阻止了就一直等
test.Set();//变成true-----将事件状态设置为终止状态,允许一个或多个等待线程继续。
test.WaitOne();//立即通过的---终止状态---线程阻止结束就继续执行
test.Reset();//重置为false---将事件状态设置为非终止状态,导致线程阻止
test.WaitOne();//是无法通过的
线程--信号量等待
ManualResetEvent test = new ManualResetEvent(false);
WaitCallback act = t =>
{
TestThread(t.ToString());
test.Set();//完成一个才为true
};
ThreadPool.QueueUserWorkItem(act, "btnThreadPool_Click");
test.WaitOne();
总结:
Thread回收比较慢,ThreadPool回收快,效果要好点。
异步是基于线程池的,但是回收的加上EndInvoke(),不然回收会比较慢.
Task and TaskFactory
private void btnTask_Click(object sender, EventArgs e)
{
Stopwatch watch = new Stopwatch();
watch.Start();
Console.WriteLine();
Console.WriteLine("*********************************btnTask_Click Start*********************************************");
Console.WriteLine("btnTask_Click当前主线程的id:{0}", Thread.CurrentThread.ManagedThreadId);
TaskFactory taskFactory = new TaskFactory();
List<Task> taskList = new List<Task>();
; i < ; i++)
{
string name = string.Format("btnTask_Click{0}", i);
Action<object> act = t => TestThread(t.ToString());
Task task = taskFactory.StartNew(act, name);
taskList.Add(task);
}
taskFactory.ContinueWhenAny(taskList.ToArray(), t =>
{
Console.WriteLine("taskFactory.ContinueWhenAny {0}", Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(t.AsyncState);
Console.WriteLine(t.IsCompleted);
});//这是回调,会等到某个Task完成后执行,不卡当前线程
taskFactory.ContinueWhenAll(taskList.ToArray(), taskArray =>
{
Console.WriteLine("taskFactory.ContinueWhenAll {0}", Thread.CurrentThread.ManagedThreadId);
foreach (var item in taskArray)
{
Console.WriteLine(item.AsyncState);
Console.WriteLine(item.IsCompleted);
}
});//这是回调,会等到全部Task完成后执行,不卡当前线程
//Task.WaitAny(taskList.ToArray());//所在的线程等待 目前在主线程 会等待某个Task的完成
//Console.WriteLine("某个Task都执行完毕了!");
//Task.WaitAll(taskList.ToArray());//所在的线程等待 目前在主线程 会等待全部Task的完成
//Console.WriteLine("所有的Task都执行完毕了!");
watch.Stop();
Console.WriteLine("*********************************btnTask_Click End {0}********************************************", watch.ElapsedMilliseconds);
Console.WriteLine();
}
Parallel
//
// 摘要:
// 尽可能并行执行提供的每个操作。
//
// 参数:
// actions:
// 要执行的 System.Action 数组。
//
// 异常:
// System.ArgumentNullException:
// actions 参数为 null。
//
// System.AggregateException:
// 当 actions 数组中的任何操作引发异常时引发的异常。
//
// System.ArgumentException:
// actions数组包含 null 个元素。
public static void Invoke(params Action[] actions);
//
// 摘要:
// 执行所提供的每个操作,而且尽可能并行运行,除非用户取消了操作。
//
// 参数:
// parallelOptions:
// 一个对象,用于配置此操作的行为。
//
// actions:
// 要执行的操作数组。
//
// 异常:
// System.OperationCanceledException:
// 设置处于 parallelOptions 中的 System.Threading.CancellationToken。
//
// System.ArgumentNullException:
// actions 参数为 null。-或- 方parallelOptions 参数为 null。
//
// System.AggregateException:
// 当 actions 数组中的任何操作引发异常时引发的异常。
//
// System.ArgumentException:
// actions 数组包含 null 元素。
//
// System.ObjectDisposedException:
// 在 parallelOptions 中与 System.Threading.CancellationToken关联的 System.Threading.CancellationTokenSource
// 已被释放。
public static void Invoke(ParallelOptions parallelOptions, params Action[] actions);
public static class Parallel
//就是在Task的基础上封装,多个任务并行计算,其实就是Task + WaitAll,而且主线程也在计算
Parallel.Invoke(() => Console.WriteLine("1 当前线程id={0}", Thread.CurrentThread.ManagedThreadId)
, () => Console.WriteLine("2 当前线程id={0}", Thread.CurrentThread.ManagedThreadId)
, () => Console.WriteLine("3 当前线程id={0}", Thread.CurrentThread.ManagedThreadId)
, () => Console.WriteLine("4 当前线程id={0}", Thread.CurrentThread.ManagedThreadId));
//计算全部完成后,才会进入下一行代码,看上去就是同步编程
Parallel.ForEach/For
Parallel.ForEach<, , , , },
t =>
{
Console.WriteLine("{0} ForEach当前线程id={1}", t, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep();
});
Parallel.For(, , t =>
{
Console.WriteLine("{0} For当前线程id={1}", t, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep();
});
可设置最大并行数
namespace System.Threading.Tasks
{
// 摘要:
// 存储用于配置 System.Threading.Tasks.Parallel 类的方法的操作的选项。
public class ParallelOptions
{
// 摘要:
// 初始化 System.Threading.Tasks.ParallelOptions 类的新实例。
public ParallelOptions();
// 摘要:
// 获取或设置与此 System.Threading.Tasks.ParallelOptions 实例关联的 System.Threading.CancellationToken。
//
// 返回结果:
// 与此实例关联的标记。
public CancellationToken CancellationToken { get; set; }
//
// 摘要:
// 获取或设置此 ParallelOptions 实例所允许的最大并行度。
//
// 返回结果:
// 一个表示最大并行度的整数。
//
// 异常:
// System.ArgumentOutOfRangeException:
// 当此 System.Threading.Tasks.ParallelOptions.MaxDegreeOfParallelism 设置为 0 或小于
// -1 的某个值时引发的异常。
public int MaxDegreeOfParallelism { get; set; }
//
// 摘要:
// 获取或设置与此 System.Threading.Tasks.ParallelOptions 实例关联的 System.Threading.Tasks.TaskScheduler。
// 将此属性设置为 null,以指示应使用当前计划程序。
//
// 返回结果:
// 与此实例关联的任务计划程序。
public TaskScheduler TaskScheduler { get; set; }
}
}
MaxDegreeOfParallelism
ParallelOptions options = new ParallelOptions()
{
MaxDegreeOfParallelism =
};
Parallel.For(, , options, t =>
{
Console.WriteLine("{0} For当前线程id={1}", t, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep();
});
ParallelLoopState
//
// 摘要:
// 执行 for(在 Visual Basic 中为 For)循环,其中可能会并行运行迭代,而且可以配置循环选项,可以监视和操作循环的状态。
//
// 参数:
// fromInclusive:
// 开始索引(含)。
//
// toExclusive:
// 结束索引(不含)。
//
// parallelOptions:
// 一个对象,用于配置此操作的行为。
//
// body:
// 将为每个迭代调用一次的委托。
//
// 返回结果:
// 包含有关已完成的循环部分的信息的结构。
//
// 异常:
// System.OperationCanceledException:
// 取消 parallelOptions 参数中的 System.Threading.CancellationToken。
//
// System.ArgumentNullException:
// body 参数为 null。-或- 方parallelOptions 参数为 null。
//
// System.AggregateException:
// 包含在所有线程上引发的全部单个异常的异常。
//
// System.ObjectDisposedException:
// 在 parallelOptions 中与 System.Threading.CancellationToken关联的 System.Threading.CancellationTokenSource
// 已被释放。
public static ParallelLoopResult For(int fromInclusive, int toExclusive, ParallelOptions parallelOptions, Action<int, ParallelLoopState> body);
ParallelLoopState
state.Break() + return;
或者 state.Stop()
ParallelOptions options = new ParallelOptions()
{
MaxDegreeOfParallelism =
};
//Parallel.For(0, 100, options, t =>
//{
// Console.WriteLine("{0} For当前线程id={1}", t, Thread.CurrentThread.ManagedThreadId);
// Thread.Sleep(3000);
//});
Parallel.For(, , options, (t, state) =>
{
Console.WriteLine("{0} For当前线程id={1}", t, Thread.CurrentThread.ManagedThreadId);
state.Break();//循环结束
//state.Stop();//paraller结束计算
return;//带上return才有效
//二者不能同时出现,会异常
Thread.Sleep();
});
多线程的临时变量
Action<int> act = i =>
{
Thread.Sleep();
Console.WriteLine(i);
};
; i < ; i++)
{
Task.Run(() => act(i));//多线程任务真的执行时,i=10了
//或者
//new Action(() => act(i)).BeginInvoke(null, null);
}
解决办法:
Action<int> act = i =>
{
Thread.Sleep();
Console.WriteLine(i);
};
; i < ; i++)
{
int k = i;//每次循环,声明一个新的变量k
Task.Run(() => act(k));
}
多线程的异常处理
TaskFactory taskFactory = new TaskFactory();
List<Task> taskList = new List<Task>();
// 通知 System.Threading.CancellationToken,告知其应被取消。
CancellationTokenSource cts = new CancellationTokenSource();
; i < ; i++)
{
string name = string.Format("btnTask_Click{0}", i);
Action<object> act = t =>
{
try
{
if (t.ToString().Equals("btnTask_Click2"))
{
throw new Exception(string.Format("{0} 执行失败", t));
}
if (t.ToString().Equals("btnTask_Click3"))
{
throw new Exception(string.Format("{0} 执行失败", t));
}
Thread.Sleep();
// 获取是否已请求取消此 System.Threading.CancellationTokenSource。
if (!cts.IsCancellationRequested)//IsCancellationRequested 被取消
{
Console.WriteLine("{0} 执行成功", t);
}
else
{
Console.WriteLine("{0} 被取消", t);
}
}
catch (Exception ex)
{
// 传达取消请求。
cts.Cancel();
Console.WriteLine("子线程异常 {0}", ex.Message);
}
};
Task task = taskFactory.StartNew(act, name, cts.Token);
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray());
; i < ; i++)
{
string name = string.Format("btnSync_Click_{0}", i);
Action<string> act = TestThread;
//act.Invoke(name);
asyncResultList.Add(act.BeginInvoke(name, null, null));
//Thread.Sleep(1);
}
//EndInvoke()
EndInvoke
using System.Threading;的更多相关文章
- .Net多线程编程—System.Threading.Tasks.Parallel
System.Threading.Tasks.Parallel类提供了Parallel.Invoke,Parallel.For,Parallel.ForEach这三个静态方法. 1 Parallel. ...
- System.Threading.Timer 定时器的用法
System.Threading.Timer 是C# 中的一个定时器,可以定时(不断循环)执行一个任务.它是在线程上执行的,具有很好的安全性.为此 .Net Framework 提供了5个重载的构造 ...
- C# System.Threading.Timer 使用方法
public class TimerHelper { System.Threading.Timer timer; public TaskSendMMS tasksendmms { get; set; ...
- C#中的线程四(System.Threading.Thread)
C#中的线程四(System.Threading.Thread) 1.最简单的多线程调用 System.Threading.Thread类构造方法接受一个ThreadStart委托,改委托不带参数,无 ...
- C#错误之 System.Threading.ThreadAbortException:正在中止线程
参考:http://www.cnblogs.com/chendaoyin/archive/2013/06/27/3159211.html 1.开启一个子线程 //开启一个子线程,子线程调用方法 Met ...
- System.Threading.Timer使用心得
System.Threading.Timer 是一个使用回调方法的计时器,而且由线程池线程服务,简单且对资源要求不高. "只要在使用 Timer,就必须保留对它的引用."对于任何托 ...
- “System.Threading.ThreadAbortException”类型的第一次机会异常在 mscorlib.dll 中发
问题原因: Thread.Abort 方法 .NET Framework 4 其他版本 1(共 1)对本文的评价是有帮助 - 评价此主题 在调用此方法的线程上引发 ThreadAbortExce ...
- System.Threading.ThreadAbortException: 正在中止线程。
在 System.Threading.ThreadAbortException 中第一次偶然出现的"mscorlib.dll"类型的异常 "System.Threadin ...
- 找不到方法"Boolean System.Threading.WaitHandle.WaitOne(TimeSpan)"的解决方案
找不到方法"Boolean System.Threading.WaitHandle.WaitOne(TimeSpan)" http://www.microsoft.com/down ...
- using System.Threading.Tasks;
using System.Threading.Tasks; .Net并行库介绍——Task1
随机推荐
- XSS攻击:SOHU视频XSS漏洞导致其用户成为DDOS肉鸡
XSS又叫CSS (Cross Site Script) ,跨站脚本攻击.恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入当中Web里面的html代码会被运行,从而达到恶意攻击用 ...
- Codeforces Round #326 (Div. 2) B. Duff in Love 分解质因数
B. Duff in Love Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/588/proble ...
- codeforces Gym 100500H A. Potion of Immortality 简单DP
Problem H. ICPC QuestTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100500/a ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 分块
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...
- myloader原理0
开源MySQL多线程逻辑导入工具myloader原理与改进 在上一篇中,介绍了多线程备份工具mydumper的实现及网易对其所做的优化,本篇聊聊与mydumper配合使用的myloader工具. my ...
- Computer Science Theory for the Information Age-6: 学习理论——VC定理的证明
VC定理的证明 本文讨论VC理论的证明,其主要内容就是证明VC理论的两个定理,所以内容非常的枯燥,但对于充实一下自己的理论知识也是有帮助的.另外,VC理论属于比较难也比较抽象的知识,所以我总结的这些证 ...
- Linux添加快捷启动方式 (Ubuntu Debian CentOS)
ubuntu桌面快捷方式的创建 debian添加快捷启动方式 centos 6 桌面建立应用程序的快捷方式的方法 今天用着用着ubuntu,突然抽搐了,感觉特别别扭,特别不方便.新装的应用程序不好 ...
- cocos2d-x lua 调用onEnter和onExit
cocos2d-x lua 调用onEnter和onExit version: cocos2d-x 3.6 onEnter和onExit在lua中不会因节点别add和remove而直接被调用,当子节点 ...
- [Java] HashMap、TreeMap、Hashtable排序
Java中对Map(HashMap,TreeMap,Hashtable等)的排序时间 首先简单说一下他们之间的区别: HashMap: 最常用的Map,它根据键的HashCode 值存储数据,根据键可 ...
- 关于错位动画的练习,原生js编写
最近在网上看到一个关于错位动画的文章,感觉非常有趣,便自己练习了一下,文章连接:http://www.w3cplus.com/animation/staggering-animations.html ...