控制台如何计算使用多线程方法运行的时间?

ft1507999 2020-01-13 05:35:44
想计算多线程执行方法的时间,但是一直无法实现,一下是我的代码,请大神指点帮忙,谢谢!
...全文
730 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
我给你解释一下,Action 以及 Func 委托都是同步顺序执行的对象。那么上面的代码把 Action集合再次重新封装转换为一个委托任务集合,转换函数过程(这里使用了 lamda 匿名表达式来简写了一下)中通过 Await Yield() 语句,告诉 c# 编译器返回的委托对象应该封装为异步任务。这就是 .net 最近6、7年的一个比较“新的”技术,就是能自动编译为 Task 或者 Task<> 对象,比之前同步的 Action 和 Func<> 更直截了当地支持异步并发编程。
  • 打赏
  • 举报
回复
另外,实际上如果你并发执行各方法时其实不想阻塞主线程,应该使用 async/await 方式将主线程过程中的语句封装。例如:
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var rnd = new Random();
var action1 = new Action(() =>
{
Thread.Sleep(rnd.Next(500, 2000));
Console.WriteLine("Action_1 执行完毕");
});
var action2 = new Action(() =>
{
Thread.Sleep(rnd.Next(500, 2000));
Console.WriteLine("Action_2 执行完毕");
});
var action3 = new Action(() =>
{
Thread.Sleep(rnd.Next(500, 2000));
Console.WriteLine("Action_3 执行完毕");
});
var action4 = new Action(() =>
{
Thread.Sleep(rnd.Next(500, 2000));
Console.WriteLine("Action_4 执行完毕");
});
var array = new Action[] { action1, action2, action3, action4 };
Console.WriteLine("同步执行array:");
foreach (var proc in array)
proc();
Console.WriteLine("并发执行array:");
Wait(array);
Console.WriteLine(".................按任意键结束");
Console.ReadKey();
}

static async void Wait(Action[] actions)
{
var tasks = actions.Select(async proc =>
{
await Task.Yield();
proc();
});
await Task.WhenAll(tasks.ToArray());
Console.WriteLine("执行array结束");
}
}
}
  • 打赏
  • 举报
回复
给你写个简单的例子。

首先要将没一个独立的程序过程封装为一个独立地Action对象,这样就容易将每一个工作真正地去认真研究、传送。

封装之后,这里就用两种方法来分别执行它们。

using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var rnd = new Random();
var action1 = new Action(() =>
{
Thread.Sleep(rnd.Next(500, 2000));
Console.WriteLine("Action_1 执行完毕");
});
var action2 = new Action(() =>
{
Thread.Sleep(rnd.Next(500, 2000));
Console.WriteLine("Action_2 执行完毕");
});
var action3 = new Action(() =>
{
Thread.Sleep(rnd.Next(500, 2000));
Console.WriteLine("Action_3 执行完毕");
});
var action4 = new Action(() =>
{
Thread.Sleep(rnd.Next(500, 2000));
Console.WriteLine("Action_4 执行完毕");
});
var array = new Action[] { action1, action2, action3, action4 };
Console.WriteLine("同步执行array:");
foreach (var proc in array)
proc();
Console.WriteLine("并发执行array:");
Wait(array);
Console.WriteLine(".................按任意键结束");
Console.ReadKey();
}

static void Wait(Action[] actions)
{
var tasks = actions.Select(async proc =>
{
await Task.Yield();
proc();
});
Task.WaitAll(tasks.ToArray());
}
}
}
圣殿骑士18 2020-01-17
  • 打赏
  • 举报
回复
搞一个实例变量,赋值一个初始时间,然后启动线程,在每个线程的方法的最后给它设置当前时间。这两个时间相减,不就是了么
圣殿骑士18 2020-01-17
  • 打赏
  • 举报
回复
引用 17 楼 wanghui0380 的回复:
[quote=引用 15 楼 圣殿骑士18 的回复:]
搞一个实例变量,赋值一个初始时间,然后启动线程,在每个线程的方法的最后给它设置当前时间。这两个时间相减,不就是了么


那再想一个问题,假设最后一个方法会在24分10秒500毫秒结束,请问我怎么知道他结束了,“薛定谔的猫”么,打开了知道结果不稀奇,麻烦在于他现在是“不知生死”[/quote]
可以发出一个事件
wanghui0380 2020-01-17
  • 打赏
  • 举报
回复
引用 15 楼 圣殿骑士18 的回复:
搞一个实例变量,赋值一个初始时间,然后启动线程,在每个线程的方法的最后给它设置当前时间。这两个时间相减,不就是了么
那再想一个问题,假设最后一个方法会在24分10秒500毫秒结束,请问我怎么知道他结束了,“薛定谔的猫”么,打开了知道结果不稀奇,麻烦在于他现在是“不知生死”
Alfred_SAMA 2020-01-17
  • 打赏
  • 举报
回复
引用 2 楼 双手暴皮 的回复:
doTestThread方法是线程体,当doTestThread执行完毕线程就执行完了,sw计时doTestThread就是线程运行的时间~
大牌鸡腿 2020-01-16
  • 打赏
  • 举报
回复

 Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            Task[] tasks = new Task[]
            {
                Task.Factory.StartNew(()=>{
                    Thread.Sleep(1000);
                }),
                Task.Factory.StartNew(()=>{
                    for (int i = 0; i < 2; i++)
                    {
                        Thread.Sleep(1000);
                    }
                }),
                  Task.Factory.StartNew(()=>{
                    for (int i = 0; i < 3; i++)
                    {
                        Thread.Sleep(1000);
                    }
                }),
            };

            Task.WaitAll(tasks);

            stopwatch.Stop();

            Console.WriteLine(stopwatch.Elapsed.TotalSeconds);
            Console.ReadKey();
st_spring 2020-01-16
  • 打赏
  • 举报
回复
引用 8 楼 ft1507999 的回复:
我有点乱了~各位大神能都给我简单讲解一下 ` 我需要的效果是, 同时执行多个线程,从开始的那一刻开始计时,一直到最后一个线程结束的时间。是否也可以这样理解,在每个线程加入单线程执行的时间,用时最长的就是所有线程执行的时间?
我觉得不是执行时间最长的吧,比如3个线程A、B、C分别执行1s、2s、3s,A线程执行1s后B、C线程开始执行,那么总花费时间算不算是4s呢
wanghui0380 2020-01-14
  • 打赏
  • 举报
回复
引用 8 楼 ft1507999 的回复:
我有点乱了~各位大神能都给我简单讲解一下 ` 我需要的效果是, 同时执行多个线程,从开始的那一刻开始计时,一直到最后一个线程结束的时间。是否也可以这样理解,在每个线程加入单线程执行的时间,用时最长的就是所有线程执行的时间?
不用解释这么多,你只有一句话“同步”,你能使用的也只有WaitHandle,哪怕那些人说task,其实依旧是还是WaitHandle
ft1507999 2020-01-14
  • 打赏
  • 举报
回复
我有点乱了~各位大神能都给我简单讲解一下 ` 我需要的效果是, 同时执行多个线程,从开始的那一刻开始计时,一直到最后一个线程结束的时间。是否也可以这样理解,在每个线程加入单线程执行的时间,用时最长的就是所有线程执行的时间?
wanghui0380 2020-01-14
  • 打赏
  • 举报
回复
WaitHandle.WaitAll() 关键字给你,自己研究一下
ft1507999 2020-01-14
  • 打赏
  • 举报
回复
意思是用task包住Thread执行吗?
datafansbj 2020-01-14
  • 打赏
  • 举报
回复
注意:Task 类是 .Net 4.0 引入的,早期版本不支持。
datafansbj 2020-01-14
  • 打赏
  • 举报
回复
考虑使用 Task,Task 是线程封装的一种类,Task.Wait 会等待指定的任务全部执行完毕,这时就可以计算总的执行时间了。
ft1507999 2020-01-14
  • 打赏
  • 举报
回复
有办法计算所有线程从开始一直到结束所花费的时间吗?
猫爪子挠 2020-01-14
  • 打赏
  • 举报
回复
doTestThread方法是线程体,当doTestThread执行完毕线程就执行完了,sw计时doTestThread就是线程运行的时间~
github_36000833 2020-01-14
  • 打赏
  • 举报
回复
测时方法可以放在doTestThread里面。

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧