发布:2021/3/6 15:45:50作者:管理员 来源:本站 浏览次数:1010
using System;}
using System;
using System.Windows.Threading;
using System.Threading;
using System.Threading.Tasks;
namespace Utils
{
/// <summary>
/// 线程帮助类(处理单线程任务)
/// </summary>
public class ThreadHelper
{
private static LimitedTaskScheduler _defaultScheduler = new LimitedTaskScheduler();
/// <summary>
/// 执行
/// 例:ThreadHelper.Run(() => { }, (ex) => { });
/// </summary>
/// <param name="doWork">在线程中执行</param>
/// <param name="errorAction">错误处理</param>
public static System.Threading.Tasks.Task Run2(Action doWork, LimitedTaskScheduler scheduler = null, Action<Exception> errorAction = null)
{
if (scheduler == null) scheduler = _defaultScheduler;
System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Factory.StartNew(() =>
{
try
{
if (doWork != null)
{
doWork();
}
}
catch (Exception ex)
{
if (errorAction != null) errorAction(ex);
LogUtil.LogError(ex);
}
}, CancellationToken.None, TaskCreationOptions.None, scheduler);
return task;
}
/// <summary>
/// 执行
/// 例:ThreadHelper.Run(() => { }, (ex) => { });
/// </summary>
/// <param name="doWork">在线程中执行</param>
/// <param name="errorAction">错误处理</param>
public static System.Threading.Tasks.Task Run(Action doWork, LimitedTaskScheduler scheduler = null, Action<Exception> errorAction = null)
{
System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Factory.StartNew(() =>
{
try
{
if (doWork != null)
{
doWork();
}
}
catch (Exception ex)
{
if (errorAction != null) errorAction(ex);
LogUtil.LogError(ex);
}
});
return task;
}
/// <summary>
/// 封装Dispatcher.BeginInvoke
/// 例:ThreadHelper.BeginInvoke(this.Dispatcher, () => { }, (ex) => { });
/// </summary>
/// <param name="errorAction">错误处理</param>
public static void BeginInvoke(Dispatcher dispatcher, Action action, Action<Exception> errorAction = null)
{
dispatcher.InvokeAsync(new Action(() =>
{
try
{
DateTime dt = DateTime.Now;
action();
double d = DateTime.Now.Subtract(dt).TotalSeconds;
if (d > 0.01) LogUtil.Log("ThreadHelper.BeginInvoke UI耗时:" + d + "秒 " + action.Target.ToString());
}
catch (Exception ex)
{
if (errorAction != null) errorAction(ex);
LogUtil.LogError(ex);
}
}), DispatcherPriority.Background);
}
}
}
private void Test23()
{
//变量定义
DateTime dt = DateTime.Now;
Random rnd = new Random();
int taskCount = 1000;
LimitedTaskScheduler scheduler = new LimitedTaskScheduler();
//生成测试数据
BlockingCollection<double> _data = new BlockingCollection<double>();
for (int i = 0; i < taskCount; i++)
{
_data.Add(rnd.NextDouble());
}
//数据计算
Thread thread = new Thread(new ThreadStart(() =>
{
dt = DateTime.Now;
for (int i = 0; i < taskCount; i++)
{
ThreadHelper.Run(() =>
{
Thread.Sleep(50);
double a;
if (_data.TryTake(out a))
{
double r = Math.PI * a;
}
}, scheduler);
}
double d = DateTime.Now.Subtract(dt).TotalSeconds;
this.BeginInvoke(new Action(() =>
{
textBox1.Text += "调用" + taskCount + "次ThreadHelper.Run耗时:" + d.ToString() + "秒\r\n";
}));
}));
thread.IsBackground = true;
thread.Start();
//数据计算耗时
Thread thread2 = new Thread(new ThreadStart(() =>
{
while (_data.Count > 0)
{
Thread.Sleep(1);
}
double d = DateTime.Now.Subtract(dt).TotalSeconds;
this.BeginInvoke(new Action(() =>
{
textBox1.Text += "数据计算结束,耗时:" + d.ToString() + "秒\r\n";
}));
}));
thread2.IsBackground = true;
thread2.Start();
scheduler.Dispose();
}
private LimitedTaskScheduler _scheduler = new LimitedTaskScheduler();
private void Test24()
{
//点击按钮耗时
DateTime dt = DateTime.Now;
ThreadHelper.Run(() =>
{
double d = DateTime.Now.Subtract(dt).TotalSeconds;
this.BeginInvoke(new Action(() =>
{
textBox1.Text += "点击按钮耗时:" + d.ToString() + "秒\r\n";
}));
}, _scheduler);
}
private void button1_Click(object sender, EventArgs e)
{
Test23();
}
private void button2_Click(object sender, EventArgs e)
{
Test24();
}
结论:使用Run,点击button2时,卡了好几秒才出来结果,而使用Run2,点击button2时,立即显示结果,button2的操作本身应该耗时极少。
现实意义:当一批耗时任务无脑使用Task.Factory.StartNew时,另一个使用Task.Factory.StartNew的任务就无法及时响应了。
© Copyright 2014 - 2024 柏港建站平台 ejk5.com. 渝ICP备16000791号-4