C# 并行线程和控制?
我有这样一个函数:C# 并行线程和控制?,c#,winforms,multithreading,.net-4.0,thread-safety,C#,Winforms,Multithreading,.net 4.0,Thread Safety,我有这样一个函数: private void GetRSS(int start, int end) { for (int i = start; i < end; i++) { string content = string.Empty; using (WebClient client = new WebClient()) { //some code here get html content
private void GetRSS(int start, int end)
{
for (int i = start; i < end; i++)
{
string content = string.Empty;
using (WebClient client = new WebClient())
{
//some code here get html content
}
// some code here parse content
}
}
然后我启动控制器,从控制器内部调用每个线程来执行上面的函数,并从控制器跟踪每个线程,比如:
private void _ControlerStart()
{
_worker1 = new Thread(GetRSS);
try
{
_worker1.Start(1, 7711);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
// repeat the above to all the 4 threads
_isRunning = true;
while (_isRunning)
{
if (_worker1.ThreadState != ThreadState.Running && _worker2.ThreadState != ThreadState.Running && _worker3.ThreadState != ThreadState.Running && _worker4.ThreadState != ThreadState.Running)
_isRunning = false;
}
MessageBox.Show("Done");
}
当我想到上面这些乱七八糟的事情时,我意识到这不是做我想做的事情的最佳方式,而我就在这里;)
我如何管理多个线程来运行同一个函数,并且能够知道每个线程何时结束工作,以关闭、保存或合并数据,或者执行主线程中剩下的任何操作?是否有不使用TPL的特定原因 正如您可能已经注意到的,提供的代码的问题在于它不是声明性的。你是在告诉机器怎么做,而不是你想做什么 在我的评论中,我建议使用 在OP的评论中,我看到 我有30k个页面要检索,每个页面上有10条记录,所以我想将30k个页面分成4个线程,在下载到字符串中后,每个页面都需要解析 第一部分定义了要执行的操作,第二部分清楚地描述了为PC牵手。我的建议是停止握住PC的手,并考虑要执行的高级操作
C#vNext对此有支持,请参见VS 2012。是否有不使用第三方物流的具体原因
private static void GetRSS(int start, int end)
{
var bunchSize = (end - start) / 4 + 1;
var threads = new List<Thread>();
for (int i = 0; i < 4; i++)
{
var currStart = start + i * bunchSize;
var currEnd = currStart + bunchSize;
if (currEnd > end)
{
currEnd = end;
}
var thread = new Thread(() =>
{
// thread logic using currStart and currEnd
string content = string.Empty;
using (WebClient client = new WebClient())
{
//some code here get html content
}
// some code here parse content
});
threads.Add(thread);
thread.Start();
}
foreach (var thread in threads)
{
thread.Join();
}
}
正如您可能已经注意到的,提供的代码的问题在于它不是声明性的。你是在告诉机器怎么做,而不是你想做什么
在我的评论中,我建议使用
在OP的评论中,我看到
我有30k个页面要检索,每个页面上有10条记录,所以我想将30k个页面分成4个线程,在下载到字符串中后,每个页面都需要解析
第一部分定义了要执行的操作,第二部分清楚地描述了为PC牵手。我的建议是停止握住PC的手,并考虑要执行的高级操作
私有静态void GetRSS(int start,int end)
private static void GetRSS(int start, int end)
{
var bunchSize = (end - start) / 4 + 1;
var threads = new List<Thread>();
for (int i = 0; i < 4; i++)
{
var currStart = start + i * bunchSize;
var currEnd = currStart + bunchSize;
if (currEnd > end)
{
currEnd = end;
}
var thread = new Thread(() =>
{
// thread logic using currStart and currEnd
string content = string.Empty;
using (WebClient client = new WebClient())
{
//some code here get html content
}
// some code here parse content
});
threads.Add(thread);
thread.Start();
}
foreach (var thread in threads)
{
thread.Join();
}
}
{
var bunchSize=(结束-开始)/4+1;
var threads=newlist();
对于(int i=0;i<4;i++)
{
var currStart=start+i*束化;
var currEnd=currStart+bunchize;
如果(当前结束>结束)
{
currEnd=结束;
}
变量线程=新线程(()=>
{
//使用currStart和currEnd的线程逻辑
string content=string.Empty;
使用(WebClient=newWebClient())
{
//这里的一些代码获取html内容
}
//这里的一些代码解析内容
});
线程。添加(线程);
thread.Start();
}
foreach(线程中的var线程)
{
thread.Join();
}
}
私有静态void GetRSS(int start,int end)
{
var bunchSize=(结束-开始)/4+1;
var threads=newlist();
对于(int i=0;i<4;i++)
{
var currStart=start+i*束化;
var currEnd=currStart+bunchize;
如果(当前结束>结束)
{
currEnd=结束;
}
变量线程=新线程(()=>
{
//使用currStart和currEnd的线程逻辑
string content=string.Empty;
使用(WebClient=newWebClient())
{
//这里的一些代码获取html内容
}
//这里的一些代码解析内容
});
线程。添加(线程);
thread.Start();
}
foreach(线程中的var线程)
{
thread.Join();
}
}
在任务方式中,您可以使用在所有任务完成后执行某些操作
private void ButtonOnClick(object sender, RoutedEventArgs routedEventArgs) {
const int n = 15;
var tasks = new Task<int>[n];
for (int i = 0; i < n; i++) {
tasks[i] = Task.Factory.StartNew(
() => {
Thread.Sleep(500);
return 100;
});
}
Task.Factory.ContinueWhenAll(
tasks,
ts => { text.Text = string.Format("Sum: {0}", ts.Sum(task => task.Result)); },
CancellationToken.None,
TaskContinuationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
}
private void按钮非点击(对象发送者,RoutedEventArgs RoutedEventArgs){
常数int n=15;
var tasks=新任务[n];
对于(int i=0;i {
睡眠(500);
返回100;
});
}
Task.Factory.continuewhalll(
任务,
ts=>{text.text=string.Format(“Sum:{0}”,ts.Sum(task=>task.Result));},
取消令牌。无,
TaskContinuationOptions。无,
TaskScheduler.FromCurrentSynchronizationContext());
}
这里我用的是
在UI线程中执行延续任务。在任务方式中,您可以使用在所有任务完成后执行某些操作
private void ButtonOnClick(object sender, RoutedEventArgs routedEventArgs) {
const int n = 15;
var tasks = new Task<int>[n];
for (int i = 0; i < n; i++) {
tasks[i] = Task.Factory.StartNew(
() => {
Thread.Sleep(500);
return 100;
});
}
Task.Factory.ContinueWhenAll(
tasks,
ts => { text.Text = string.Format("Sum: {0}", ts.Sum(task => task.Result)); },
CancellationToken.None,
TaskContinuationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
}
private void按钮非点击(对象发送者,RoutedEventArgs RoutedEventArgs){
常数int n=15;
var tasks=新任务[n];
对于(int i=0;i