我认为可以用Thread.CurrentThread.ManagedThreadId
解决方案 »
- 调试自动结束
- ds.Dispose(); return ds;请问返回的是空的还是?? 为什么我测试后,返回并非null呢??好像并没有清空ds?????
- 监视U盘,子类中不行,主窗体中可以,为什么?在线等!本人结贴率100%
- 求救SQL 语句问题,高手请进。。
- vss创建文件的时候,有个多选框,提示只保留最新版本
- 请高手赐教关于c#窗体画图的问题
- 求1+2!+3!+...+20!的和
- 50分在线求一正则表达式
- C#如何遍历修改ACCESS数据库的指定字字段?
- 问个很傻的问题 请不要笑我
- 如何将数据写入到数据库中的表中(c#连接sql数据库)
- 求助!!如何把datagridview 内的数据 推送到 report
ManagedThreadId值一样就表示一定是同一个线程了吗?
{
Thread th1 = new Thread(o => { Method1(); Method2(); }) { Name = "th1" };
Thread th2 = new Thread(o => { Method1(); }) { Name = "th2" };
Thread th3 = new Thread(o => { Method2(); }) { Name = "th3" };
th1.Start();
th2.Start();
th3.Start();
Console.Read();
}
static void Method1()
{
Console.WriteLine(Thread.CurrentThread.Name);
} static void Method2()
{
Console.WriteLine(Thread.CurrentThread.Name);
}
System.Threading.Parallel 提供了几种实用的循环并行处理方法,让我们可以用非常简便的代码完成并发处理。1. For
var datas = new[] { "a", "b", "c" };Parallel.For(0, datas.Length, i =>
{
var s = datas[i];
Console.WriteLine(">>> Thread:{0}, {1}", Thread.CurrentThread.ManagedThreadId, s);
});输出:
>>> Thread:3, a
>>> Thread:7, b
>>> Thread:5, c我们还可以像 for(;; i += 2) 那样指定循环递增幅度。
var datas = new[] { "a", "b", "c", "d", "e" };Parallel.For(0, datas.Length, 2, i =>
{
var s = datas[i];
Console.WriteLine(">>> Thread:{0}, {1}", Thread.CurrentThread.ManagedThreadId, s);
});for (int i = 0; i < datas.Length; i += 2)
{
Console.WriteLine(datas[i]);
}输出:
>>> Thread:3, a
>>> Thread:7, e
>>> Thread:4, c
a
c
eFor() 还提供了更多更复杂的重载,包括提供 init、finally、state 等操作。比如,我们可以通过调用 ParallelState.Stop() 来停止后续处理。
var datas = new[] { "a", "b", "c", "d", "e" };Parallel.For(0, datas.Length, (i, state) =>
{
state.Stop(); var s = datas[i];
Console.WriteLine(">>> Thread:{0}, {1}",
Thread.CurrentThread.ManagedThreadId, s);
});输出:
>>> Thread:3, a
>>> Thread:7, b
>>> Thread:5, c还可以像下面这样,添加初始化、结束处理委托,并传递额外的参数给并行代码。
var datas = new[] { "a", "b" };Parallel.For<int>(0, datas.Length,
() =>
{
Console.WriteLine("Init {0}...", Thread.CurrentThread.ManagedThreadId);
return 123;
},
(i, state) =>
{
state.Stop(); var s = datas[i];
Console.WriteLine(">>> Thread:{0}, {1}, {2}",
Thread.CurrentThread.ManagedThreadId, s, state.ThreadLocalState);
},
(x) =>
{
Console.WriteLine("Finally {0}, {1}...", Thread.CurrentThread.ManagedThreadId, x);
});输出:
Init 3...
Init 5...
>>> Thread:3, a, 123
>>> Thread:5, b, 123
Finally 3, 123...
Finally 5, 123...2. ForeachForEach() 和 For() 的用法非常类似。
var datas = new[] { "a", "b", "c", "d", "e" };Parallel.ForEach(datas, s =>
{
Console.WriteLine(">>> thread:{0}, {1}",
Thread.CurrentThread.ManagedThreadId, s);
});输出:
>>> thread:3, a
>>> thread:6, b
>>> thread:5, c
>>> thread:6, e
>>> thread:7, d作者善解人意,同样提供了多种重载,包括获取索引位置以及并发状态管理等等。
var datas = new[] { "a", "b", "c", "d", "e" };Parallel.ForEach(datas, (s, i, state) =>
{
Console.WriteLine(">>> thread:{0}, index:{1}, {2}",
Thread.CurrentThread.ManagedThreadId, i, s);
});输出:
>>> thread:3, index:0, a
>>> thread:7, index:3, d
>>> thread:6, index:2, c
>>> thread:7, index:4, e
>>> thread:5, index:1, b3. InvokeInvoke 针对的是 "并发逻辑" 而非 "并发数据"。当然,我们也可以将 "并发逻辑" 打包成数据集合(Delegate[]) 提交给 For/Foreach 执行,只不过 Invoke 更简便一些。
Parallel.Invoke(new Action[]
{
() => Console.WriteLine(">>> thread:{0}, {1}", Thread.CurrentThread.ManagedThreadId, 1),
() => Console.WriteLine(">>> thread:{0}, {1}", Thread.CurrentThread.ManagedThreadId, "a"),
() => Console.WriteLine(">>> thread:{0}, {1}", Thread.CurrentThread.ManagedThreadId, typeof(object)),
});输出:
>>> thread:3, 1
>>> thread:5, System.Object
>>> thread:4, a改用 TPL / Invoke 写蜘蛛(Spider/Crawler)抓取代码,可以大大简化代码样式,少了许多线程管理调度
{
System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadTest));
thread.Name = "线程1的名字";
thread.Start();
}
private void ThreadTest()
{
MessageBox.Show(System.Threading.Thread.CurrentThread.Name);
}除了获取线程ID以外,可以指定线程的名字,用来区别于其他线程的哈,因为用线程ID不能具体知道是什么线程,所以用线程名字更科学一些。楼主可以测试一下上面的代码,我测试通过了。
线程也有一个托管的线程ID,可以用ManagedThreadId属性读取它。
参考