分享一个UI多任务阻塞处理的源代码
问题在这里http://bbs.csdn.net/topics/390369970
既要阻塞UI线程等待非UI线程结束,又要在非UI线程中进行UI操作,简单的Wait肯定会造成死锁。
因为很多时候UI与非UI操作夹杂在一起,写程序很方便。
为了解决这个问题,所以我写了一个比较通用的基于fastCSharp处理类。
就是建立一个UI任务队列,UI线程Wait新任务,非UI线程Pulse唤醒UI线程。
using System;
using System.Threading;
using fastCSharp;
using fastCSharp.threading;
namespace showjim.console
{
/// <summary>
/// UI多任务阻塞处理
/// </summary>
public class uiWait
{
/// <summary>
/// 任务信息
/// </summary>
private class taskInfo
{
/// <summary>
/// 执行委托
/// </summary>
public action Action;
/// <summary>
/// 等待完成锁
/// </summary>
public object WaitLock;
/// <summary>
/// 任务是否已完成
/// </summary>
public bool isFinally;
/// <summary>
/// 等待任务完成
/// </summary>
public void Wait()
{
Monitor.Enter(WaitLock);
try
{
if (!isFinally) Monitor.Wait(WaitLock);
}
finally { Monitor.Exit(WaitLock); }
}
/// <summary>
/// 执行任务
/// </summary>
public void Run()
{
if (Action != null)
{
try
{
Action();
}
catch (Exception error)
{
fastCSharp.log.Default.Add(error, null, false);
}
}
if (WaitLock != null)
{
isFinally = true;
Monitor.Enter(WaitLock);
try
{
Monitor.Pulse(WaitLock);
}
finally { Monitor.Exit(WaitLock); }
}
}
}
/// <summary>
/// 非UI任务
/// </summary>
private readonly task task;
/// <summary>
/// UI任务集合
/// </summary>
private list<taskInfo> tasks = new list<taskInfo>();
/// <summary>
/// UI任务访问锁
/// </summary>
private readonly object taskLock = new object();
/// <summary>
/// 是否开始运行UI任务
/// </summary>
private bool isRun;
/// <summary>
/// 是否以线程的方式运行UI任务
/// </summary>
private bool isRunThread;
/// <summary>
/// 非UI任务是否已完成
/// </summary>
private bool isTaskFinally;
/// <summary>
/// UI任务是否已完成
/// </summary>
private bool isFinally;
/// <summary>
/// UI任务完成锁
/// </summary>
private readonly object finallyLock = new object();
/// <summary>
/// UI多任务阻塞处理
/// </summary>
/// <param name="task">非UI任务</param>
public uiWait(task task)
{
if (task == null) fastCSharp.log.Default.Throw(log.exceptionType.Null);
this.task = task;
}
/// <summary>
/// 添加新的UI任务
/// </summary>
/// <param name="task">任务信息</param>
private void add(taskInfo task)
{
Monitor.Enter(taskLock);
try
{
tasks.Add(task);
Monitor.Pulse(taskLock);
}
finally { Monitor.Exit(taskLock); }
}
/// <summary>
/// 添加新的UI任务
/// </summary>
/// <param name="run">任务执行委托</param>
public void Add(action run)
{
if (run != null) add(new taskInfo { Action = run });
}
/// <summary>
/// 添加新的UI任务
/// </summary>
/// <typeparam name="parameterType">任务参数类型</typeparam>
/// <param name="run">任务执行委托</param>
/// <param name="parameter">任务参数</param>
public void Add<parameterType>(action<parameterType> run, parameterType parameter)
{
if (run != null) add(new taskInfo { Action = run<parameterType>.Create(run, parameter) });
}
/// <summary>
/// 添加新的UI任务并同步等待任务完成
/// </summary>
/// <param name="info">任务信息</param>
private void addWait(taskInfo info)
{
add(info);
info.Wait();
}
/// <summary>
/// 添加新的UI任务并同步等待任务完成
/// </summary>
/// <param name="run">任务执行委托</param>
public void AddWait(action run)
{
addWait(new taskInfo { Action = run, WaitLock = new object() });
}
/// <summary>
/// 添加新的UI任务并同步等待任务完成
/// </summary>
/// <typeparam name="parameterType">任务参数类型</typeparam>
/// <param name="run">任务执行委托</param>
/// <param name="parameter">任务参数</param>
public void AddWait<parameterType>(action<parameterType> run, parameterType parameter)
{
addWait(new taskInfo { Action = run<parameterType>.Create(run, parameter), WaitLock = new object() });
}
/// <summary>
/// 检测是否开始运行UI任务
/// </summary>
private void checkRun()
{
Monitor.Enter(taskLock);
try
{
if (isRun) fastCSharp.log.Default.ThrowReal(log.exceptionType.ErrorOperation);
isRun = true;
}
finally { Monitor.Exit(taskLock); }
}
/// <summary>
/// 等待非UI任务结束
/// </summary>
private void wait()
{
task.Dispose(true);
isTaskFinally = true;
Monitor.Enter(taskLock);
try
{
Monitor.Pulse(taskLock);
}
finally { Monitor.Exit(taskLock); }
}
/// <summary>
/// 执行UI任务
/// </summary>
private void run()
{
list<taskInfo> runTasks = new list<taskInfo>(), oldTasks;
while (true)
{
Monitor.Enter(taskLock);
try
{
if (tasks.Count == 0)
{
if (isTaskFinally) break;
Monitor.Wait(taskLock);
}
oldTasks = runTasks;
runTasks = tasks;
tasks = oldTasks;
}
finally { Monitor.Exit(taskLock); }
foreach (taskInfo task in runTasks) task.Run();
runTasks.Empty();
}
isFinally = true;
Monitor.Enter(finallyLock);
try
{
Monitor.Pulse(finallyLock);
}
finally { Monitor.Exit(finallyLock); }
}
/// <summary>
/// 异步执行UI任务
/// </summary>
public void RunThread()
{
checkRun();
new thread(wait).Start();
new thread(run).Start();
isRunThread = true;
}
/// <summary>
/// 等待异步执行UI任务结束
/// </summary>
public void WaitThread()
{
if (isRunThread)
{
Monitor.Enter(finallyLock);
try
{
if (!isFinally) Monitor.Wait(finallyLock);
}
finally { Monitor.Exit(finallyLock); }
}
else fastCSharp.log.Default.ThrowReal(log.exceptionType.ErrorOperation);
}
/// <summary>
/// 执行UI任务并等待任务结束
/// </summary>
public void Wait()
{
checkRun();
new thread(wait).Start();
run();
}
}
}
支持同步与异步两种模式,uiWait是一个实例
[解决办法]
好东西,支持一下
[解决办法]
好东西,感谢分享
[解决办法]
感谢分享,帮你顶下。
[解决办法]
必须要顶

[解决办法]
收藏下,以后可能有用
[解决办法]
收藏下,以后可能有用
[解决办法]
非常有用,谢谢分享!
[解决办法]
if (run != null) add(new taskInfo { Action = run<parameterType>.Create(run, parameter) });
报错
[解决办法]
Mark,感谢分享!
[解决办法]
if (run != null) add(new taskInfo { Action = run<parameterType>.Create(run, parameter) });
报错!
[解决办法]
不知道用不用得到,先看看
------解决方案--------------------
先预备着,谢谢LZ
[解决办法]

[解决办法]

[解决办法]