343 lines
11 KiB
C#
343 lines
11 KiB
C#
using System.Collections.Concurrent;
|
|
|
|
namespace YLErp.Helpers
|
|
{
|
|
//public enum ProgressName
|
|
//{
|
|
// ClientBalanceReport
|
|
//}
|
|
|
|
public static class ProgressHelper<T>
|
|
{
|
|
|
|
static ConcurrentDictionary<string, ProgressInfo<T>> goingTasks = new ConcurrentDictionary<string, ProgressInfo<T>>();
|
|
private static readonly object _asyncLock = new object();
|
|
|
|
public static bool Start(IEnumerable<T> inputList, string key, Func<T, string> callback)
|
|
{
|
|
lock (_asyncLock)
|
|
{
|
|
if (goingTasks.TryGetValue(key, out var ret) && ret.status == ProgressBarStatus.IDLE)
|
|
{
|
|
goingTasks.TryRemove(key, out _);
|
|
}
|
|
if (goingTasks.TryAdd(key, new ProgressInfo<T>(inputList, callback)))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static bool Start(IEnumerable<T> inputList, string key, Func<T, object, string> callback, object extendParams)
|
|
{
|
|
lock (_asyncLock)
|
|
{
|
|
if (goingTasks.TryGetValue(key, out var ret) && ret.status == ProgressBarStatus.IDLE)
|
|
{
|
|
goingTasks.TryRemove(key, out _);
|
|
}
|
|
if (goingTasks.TryAdd(key, new ProgressInfo<T>(inputList, callback, extendParams)))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static bool Start(IEnumerable<T> inputList, string key, Func<T, object, string> callback, Func<object, object> finalFunc, object extendParams)
|
|
{
|
|
lock (_asyncLock)
|
|
{
|
|
if (goingTasks.TryGetValue(key, out var ret) && ret.status == ProgressBarStatus.IDLE)
|
|
{
|
|
goingTasks.TryRemove(key, out _);
|
|
}
|
|
if (goingTasks.TryAdd(key, new ProgressInfo<T>(inputList, callback, finalFunc, extendParams)))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static bool Start(IEnumerable<T> inputList, string key, Func<T, object, ProgressInfo<T>, string> callback, Func<object, object> finalFunc, object extendParams)
|
|
{
|
|
lock (_asyncLock)
|
|
{
|
|
if (goingTasks.TryAdd(key, new ProgressInfo<T>(inputList, callback, finalFunc, extendParams)))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static ProgressInfo<T> ObservateProcess(string key)
|
|
{
|
|
if (goingTasks.ContainsKey(key))
|
|
{
|
|
|
|
var ret = goingTasks[key];
|
|
if (ret.status == ProgressBarStatus.IDLE)
|
|
{
|
|
goingTasks.TryRemove(key, out ret);
|
|
}
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static bool Stop(string key)
|
|
{
|
|
if (goingTasks.ContainsKey(key))
|
|
{
|
|
|
|
var ret = goingTasks[key];
|
|
if (ret.status == ProgressBarStatus.IDLE)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
ret.status = ProgressBarStatus.STOPPING;
|
|
}
|
|
goingTasks.TryRemove(key, out _);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
public class ProgressInfo<T>
|
|
{
|
|
public int total { get; private set; }
|
|
public int done { get; private set; }
|
|
public List<string> message { get; private set; }
|
|
public ProgressBarStatus status { get; set; }
|
|
|
|
public bool ignoreIndex { get; set; }
|
|
|
|
/// <summary>
|
|
/// 保存 finalFunc 的返回值,传到前端;
|
|
/// </summary>
|
|
public object resultObj { get; private set; }
|
|
|
|
public ProgressInfo(IEnumerable<T> goings, Func<T, string> del)
|
|
{
|
|
this.total = goings.Count();
|
|
this.done = 0;
|
|
this.status = ProgressBarStatus.RUNNING;
|
|
message = new List<string>();
|
|
Thread th = new Thread(() => DoProgress(goings, del));
|
|
th.Start();
|
|
}
|
|
|
|
public ProgressInfo(IEnumerable<T> goings, Func<T, object, string> del, object extendParams)
|
|
{
|
|
this.total = goings.Count();
|
|
this.done = 0;
|
|
this.status = ProgressBarStatus.RUNNING;
|
|
message = new List<string>();
|
|
Thread th = new Thread(() => DoProgress(goings, del, extendParams));
|
|
th.Start();
|
|
}
|
|
|
|
public ProgressInfo(IEnumerable<T> goings, Func<T, object, string> del, Func<object, object> final, object extendParams)
|
|
{
|
|
this.total = goings.Count();
|
|
this.done = 0;
|
|
this.status = ProgressBarStatus.RUNNING;
|
|
message = new List<string>();
|
|
Thread th = new Thread(() => DoProgress(goings, del, final, extendParams));
|
|
th.Start();
|
|
}
|
|
|
|
public ProgressInfo(IEnumerable<T> goings, Func<T, object, ProgressInfo<T>, string> del, Func<object, object> final, object extendParams)
|
|
{
|
|
this.total = goings.Count();
|
|
this.done = 0;
|
|
this.status = ProgressBarStatus.RUNNING;
|
|
message = new List<string>();
|
|
Thread th = new Thread(() => DoProgress(goings, del, final, extendParams));
|
|
th.Start();
|
|
}
|
|
void DoProgress(IEnumerable<T> input, Func<T, string> callback)
|
|
{
|
|
try
|
|
{
|
|
foreach (var item in input)
|
|
{
|
|
if (this.status != ProgressBarStatus.RUNNING)
|
|
{
|
|
break;
|
|
}
|
|
try
|
|
{
|
|
this.message.Add(callback(item));
|
|
}
|
|
catch (Exception ex) { LogFactory.GetLogger("ProgressHelper").Error(ex); }
|
|
if (this.done < this.total)
|
|
{
|
|
this.done++;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogFactory.GetLogger("ProgressHelper").Error("进度无法继续:" + ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
this.status = ProgressBarStatus.IDLE;
|
|
}
|
|
}
|
|
|
|
void DoProgress(IEnumerable<T> input, Func<T, object, string> callback, object extendParams)
|
|
{
|
|
try
|
|
{
|
|
foreach (var item in input)
|
|
{
|
|
if (this.status != ProgressBarStatus.RUNNING)
|
|
{
|
|
break;
|
|
}
|
|
try
|
|
{
|
|
this.message.Add(callback(item, extendParams));
|
|
}
|
|
catch (Exception ex) { LogFactory.GetLogger("ProgressHelper").Error(ex); }
|
|
if (this.done < this.total)
|
|
{
|
|
this.done++;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogFactory.GetLogger("ProgressHelper").Error("进度无法继续:" + ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
this.status = ProgressBarStatus.IDLE;
|
|
}
|
|
}
|
|
|
|
void DoProgress(IEnumerable<T> input, Func<T, object, string> callback, Func<object, object> finalFunc, object extendParams)
|
|
{
|
|
try
|
|
{
|
|
foreach (var item in input)
|
|
{
|
|
if (this.status != ProgressBarStatus.RUNNING)
|
|
{
|
|
break;
|
|
}
|
|
try
|
|
{
|
|
this.message.Add(callback(item, extendParams));
|
|
}
|
|
catch (Exception ex) { LogFactory.GetLogger("ProgressHelper").Error(ex); }
|
|
if (this.done < this.total)
|
|
{
|
|
this.done++;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogFactory.GetLogger("ProgressHelper").Error("进度无法继续:" + ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
try
|
|
{
|
|
if (this.status == ProgressBarStatus.RUNNING)
|
|
{
|
|
resultObj = finalFunc(extendParams);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogFactory.GetLogger("ProgressHelper").Error("进度完成时出错:" + e.Message);
|
|
}
|
|
finally
|
|
{
|
|
this.status = ProgressBarStatus.IDLE;
|
|
}
|
|
}
|
|
}
|
|
|
|
void DoProgress(IEnumerable<T> input, Func<T, object, ProgressInfo<T>, string> callback, Func<object, object> finalFunc, object extendParams)
|
|
{
|
|
try
|
|
{
|
|
foreach (var item in input)
|
|
{
|
|
if (this.status != ProgressBarStatus.RUNNING)
|
|
{
|
|
break;
|
|
}
|
|
try
|
|
{
|
|
this.message.Add(callback(item, extendParams, this));
|
|
}
|
|
catch (Exception ex) { LogFactory.GetLogger("ProgressHelper").Error(ex); }
|
|
if (this.ignoreIndex)
|
|
{
|
|
this.message.Add(callback(item, extendParams, this));
|
|
}
|
|
if (this.done < this.total)
|
|
{
|
|
this.done++;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogFactory.GetLogger("ProgressHelper").Error("进度无法继续:" + ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
try
|
|
{
|
|
if (this.status == ProgressBarStatus.RUNNING)
|
|
{
|
|
resultObj = finalFunc(extendParams);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogFactory.GetLogger("ProgressHelper").Error("进度完成时出错:" + e.Message);
|
|
}
|
|
finally
|
|
{
|
|
this.status = ProgressBarStatus.IDLE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public enum ProgressBarStatus
|
|
{
|
|
/// <summary>
|
|
/// 空闲
|
|
/// </summary>
|
|
IDLE,
|
|
/// <summary>
|
|
/// 运行中
|
|
/// </summary>
|
|
RUNNING,
|
|
/// <summary>
|
|
/// 停止中
|
|
/// </summary>
|
|
STOPPING,
|
|
}
|
|
}
|