tec*_*hno -1 .net c# multithreading task winforms
我正在使用以下方法创建新任务并长时间在后台执行操作.如果满足某个条件,我需要完全停止所有任务并向用户显示消息.
dowork()
{
mylist = new List<DataModel.CheckData>();
int index = 0;
foreach (var line in mylist)
{
mylist.Add(new DataModel.CheckData() { RawLine = line, data = line,FileName=virtualfilelist[index].ToString() });
index++;
}
BlockingCollection<DataModel.CheckData> ujobs = new BlockingCollection<DataModel.CheckData>();
timerRefreshUi.Start();
Task.Factory.StartNew(() =>
{
_dtRows.Clear();
uiQueue.Clear();
uiQueueBad.Clear();
uiQueueGood.Clear();
for (int i = 0; i < mylist.Count; i++)
{
AddResultRow(mylist[i].data, "Waiting...",mylist[i].FileName, Color.White);
ujobs.TryAdd(new DataModel.CheckData() { RowId = i, data = mylist[i].data }, 1000);
}
List<Task> openCheckTasks = new List<Task>();
while (ujobs.Count > 0)
{
while (openCheckTasks.Where(task => task.Status == TaskStatus.Running).ToList().Count >= threadcount)
System.Threading.Thread.Sleep(250);
Task t = new Task(new Action(() =>
{
}));
openCheckTasks.Add(t);
t.Start();
}
Task.WaitAll(openCheckTasks.ToArray());
}).ContinueWith(task => {
_benchmark.Stop();
this.BeginInvoke(new Action(() =>
{
}));
});
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试使用Cancellation Token和break在while循环中.但是它无法正常工作.请建议停止所有线程的最佳方法.我对多线程编程的经验很少.
tin*_*udu 10
CancellationToken 是正确的方法.
您是否试图控制一次运行多少任务?这就是TPL已经做过的事情,而且做得很好.
请参阅此示例,启动许多CPU密集型任务,然后在三秒后取消所有这些任务:
public static void Main()
{
var delay = TimeSpan.FromSeconds(1);
var cts = new CancellationTokenSource();
var tasks = Enumerable.Range(0, 100).Select(i => Task.Run(() => SlowSqrt/*Async*/(i, delay, cts.Token), cts.Token)).ToArray();
Thread.Sleep(3000);
cts.Cancel();
}
public static double SlowSqrt(double arg, TimeSpan delay, CancellationToken token)
{
Console.WriteLine($"Calculating Sqrt({arg})...");
var burnCpuTimeUntil = DateTime.Now + delay;
while (DateTime.Now < burnCpuTimeUntil) token.ThrowIfCancellationRequested();
var result = Math.Sqrt(arg);
Console.WriteLine($"Sqrt({arg}) is {result}.");
return result;
}
public static async Task<double> SlowSqrtAsync(double arg, TimeSpan delay, CancellationToken token)
{
Console.WriteLine($"Calculating Sqrt({arg})...");
await Task.Delay(delay, token);
var result = Math.Sqrt(arg);
Console.WriteLine($"Sqrt({arg}) is {result}.");
return result;
}
Run Code Online (Sandbox Code Playgroud)
其输出是:
Calculating Sqrt(1)...
Calculating Sqrt(2)...
Calculating Sqrt(0)...
Calculating Sqrt(3)...
Sqrt(2) is 1.4142135623731.
Calculating Sqrt(4)...
Sqrt(0) is 0.
Calculating Sqrt(5)...
Sqrt(3) is 1.73205080756888.
Calculating Sqrt(6)...
Sqrt(1) is 1.
Calculating Sqrt(7)...
Sqrt(5) is 2.23606797749979.
Calculating Sqrt(8)...
Sqrt(4) is 2.
Calculating Sqrt(9)...
Sqrt(6) is 2.44948974278318.
Calculating Sqrt(10)...
Sqrt(7) is 2.64575131106459.
Calculating Sqrt(11)...
Run Code Online (Sandbox Code Playgroud)
由于我的计算机上有四个核心,因此一次只能激活4个任务.取消令牌时(12..99)尚未启动的任务甚至都没有开始.启动的任务(8..11)出错token.ThrowIfCancellationRequested().所有这些都在TaskStatus.Canceled州内结束.
现在,如果您更改上面的代码以进行调用SlowSqrtAsync,则1秒延迟不会使用CPU,因此TPL会激活所有100个任务,尝试最大化CPU使用率.大约一秒钟后,您将获得所有100个结果.如果你取消了任务,而这是里面的Task.Delay,它会抛出OperationCanceledException一样Token.ThrowIfCancellationRequested()会做.
Calculating Sqrt(0)...
Calculating Sqrt(1)...
:
:
Calculating Sqrt(92)...
Calculating Sqrt(89)...
(about 1 second later:)
Sqrt(19) is 4.35889894354067.
Sqrt(5) is 2.23606797749979.
:
:
Sqrt(99) is 9.9498743710662.
Sqrt(92) is 9.59166304662544.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
534 次 |
| 最近记录: |