C# 从listview创建和停止线程
我需要您的帮助,对于线程,我已满0,您只需要创建一个特定线程并在命令下完成它,但我不会提前创建每个线程,因为会有很多线程,我是这样做的:C# 从listview创建和停止线程,c#,multithreading,C#,Multithreading,我需要您的帮助,对于线程,我已满0,您只需要创建一个特定线程并在命令下完成它,但我不会提前创建每个线程,因为会有很多线程,我是这样做的: Thread thread = new Thread(() => Go(..... many many variables that are taken from the listview ......)); thread.Start(); 因此,如上所述,变量取自listview,我从文件中加载listview,然后运行所需的线程。但是流中的进程是无
Thread thread = new Thread(() => Go(..... many many variables that are taken from the listview ......));
thread.Start();
因此,如上所述,变量取自listview,我从文件中加载listview,然后运行所需的线程。但是流中的进程是无限的,只有当我完全关闭程序时才会结束,并且我希望以与启动流相同的方式结束流(右键单击所需的行start/stop)。正如我所说的,我从来没有使用过线程,我认为这很简单,比如当你开始一个线程时,你给它分配了一个ID,然后用相同的ID结束它,但是唉。我在谷歌上搜索了很多次,没有找到一个适合我的例子(我将第三次重复——我从来没有使用过线程,我不需要说“去阅读关于TPL的文章”),所以我请求帮助,最好是举个例子)
我有一个非常糟糕的想法:在工作表中有一个不可见的列,其中一个id在开始时生成,然后当我发送一个命令来启动线程时,会创建一个名为int id1=0的唯一变量,它的名称会传递给线程本身,每次循环启动时,id1=0或1会分别在其中被选中,如果0-继续,如果1-空。那么,当你点击停止按钮时,它的值变为1是合乎逻辑的。但在我看来,当线程变成100+时,多线程的圣灵会因此惩罚我。我在某个地方读到过这个想法,所以不要发誓)你不需要数百条线程来完成这个任务。您的工作线程正在执行HTTP请求,这可以在不需要新线程的情况下异步完成。此外,除非您有数百个CPU内核(您没有),否则数百个线程也不会真正帮助您 对于这类工作,我建议如下:
CancellationToken
取消令牌
public async Task DoTheWork(Account account, CancellationToken token)
{
while (!token.IsCancellationRequested)
{
var result = await httpClient.GetAsync(account.Url);
await DoSomethingWithResult(result);
await Task.Delay(1000);
}
}
//Main program
var accounts = GetAccountList();
var source = new CancellationTokenSource();
var tasks = accounts.Select( x => DoTheWork(x, source.Token) ).ToList();
//When exiting
source.Cancel();
await Task.WhenAll( tasks );
source.Dispose();
个别取消
下面是另一种方法,它保存一个帐户列表和一个可用于取消该特定帐户任务的委托
//Declare this somewhere it will persist for the duration of the program
//The key to this dictionary is the account you wish to cancel
//The value is a delegate that you can call to cancel its task
Dictionary<Account, Func<Task>> _tasks = new Dictionary<Account, Func<Task>>();
async Task CreateTasks()
{
var accounts = GetAccounts();
foreach (var account in accounts)
{
var source = new CancellationTokenSource();
var task = DoTheWork(account, source.Token);
_tasks.Add(account, () => { source.Cancel(); return task; });
}
}
//Retrieve the delegate from the dictionary and call it to cancel its task
//Then await the task to observe any exceptions
//Then remove it from the list
async Task CancelTask(Account account)
{
var cancelAction = _tasks[account];
var task = cancelAction();
await task;
_tasks.Remove(account);
}
async Task CancelAllTasks()
{
var tasks = _tasks.Select(x => x.Value()).ToList();
await Task.WhenAll(tasks);
}
//在某个地方声明它将在程序执行期间保持不变
//此词典的密钥是您要取消的帐户
//该值是可以调用以取消其任务的委托
字典_tasks=新字典();
异步任务CreateTasks()
{
var accounts=GetAccounts();
foreach(账户中的var账户)
{
var source=新的CancellationTokenSource();
var task=DoTheWork(account,source.Token);
_添加(帐户,()=>{source.Cancel();返回任务;});
}
}
//从字典中检索委托并调用它以取消其任务
//然后等待任务观察任何异常
//然后将其从列表中删除
异步任务取消任务(帐户)
{
var cancelAction=_任务[帐户];
var task=cancelAction();
等待任务;
_任务。删除(帐户);
}
异步任务CancelAllTasks()
{
var tasks=_tasks.Select(x=>x.Value()).ToList();
等待任务。何时(任务);
}
此操作不需要数百个线程。您的工作线程正在执行HTTP请求,这可以在不需要新线程的情况下异步完成。此外,除非您有数百个CPU内核(您没有),否则数百个线程也不会真正帮助您
对于这类工作,我建议如下:
CancellationToken
取消令牌
public async Task DoTheWork(Account account, CancellationToken token)
{
while (!token.IsCancellationRequested)
{
var result = await httpClient.GetAsync(account.Url);
await DoSomethingWithResult(result);
await Task.Delay(1000);
}
}
//Main program
var accounts = GetAccountList();
var source = new CancellationTokenSource();
var tasks = accounts.Select( x => DoTheWork(x, source.Token) ).ToList();
//When exiting
source.Cancel();
await Task.WhenAll( tasks );
source.Dispose();
个别取消
下面是另一种方法,它保存一个帐户列表和一个可用于取消该特定帐户任务的委托
//Declare this somewhere it will persist for the duration of the program
//The key to this dictionary is the account you wish to cancel
//The value is a delegate that you can call to cancel its task
Dictionary<Account, Func<Task>> _tasks = new Dictionary<Account, Func<Task>>();
async Task CreateTasks()
{
var accounts = GetAccounts();
foreach (var account in accounts)
{
var source = new CancellationTokenSource();
var task = DoTheWork(account, source.Token);
_tasks.Add(account, () => { source.Cancel(); return task; });
}
}
//Retrieve the delegate from the dictionary and call it to cancel its task
//Then await the task to observe any exceptions
//Then remove it from the list
async Task CancelTask(Account account)
{
var cancelAction = _tasks[account];
var task = cancelAction();
await task;
_tasks.Remove(account);
}
async Task CancelAllTasks()
{
var tasks = _tasks.Select(x => x.Value()).ToList();
await Task.WhenAll(tasks);
}
//在某个地方声明它将在程序执行期间保持不变
//此词典的密钥是您要取消的帐户
//该值是可以调用以取消其任务的委托
字典_tasks=新字典();
异步任务CreateTasks()
{
var accounts=GetAccounts();
foreach(账户中的var账户)
{
var source=新的CancellationTokenSource();
var task=DoTheWork(account,source.Token);
_添加(帐户,()=>{source.Cancel();返回任务;});
}
}
//从字典中检索委托并调用它以取消其任务
//然后等待任务观察任何异常
//然后将其从列表中删除
异步任务取消任务(帐户)
{
var cancelAction=_任务[帐户];
var task=cancelAction();
等待任务;
_任务。删除(帐户);
}
异步任务CancelAllTasks()
{
var tasks=_tasks.Select(x=>x.Value()).ToList();
等待任务。何时(任务);
}
在现代c#中,您可能不应该直接使用线程(除非您是非常高级的开发人员,并且有令人信服的理由)。还有许多其他语言功能可用于处理多个任务,例如异步任务
、TPL和