Compare commits
2 Commits
95db87e1bd
...
9c6a653b91
| Author | SHA1 | Date |
|---|---|---|
|
|
9c6a653b91 | |
|
|
f440a45325 |
|
|
@ -8,23 +8,23 @@ namespace ZTools
|
|||
public class ZCalendar : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据更新时,可获取到每一个日期,并对其进行操作
|
||||
/// <EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>ɻ<EFBFBD>ȡ<EFBFBD><EFBFBD>ÿһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public event Action<ZCalendarDayItem> UpdateDateEvent;
|
||||
/// <summary>
|
||||
/// 可以获取到点击的某一天
|
||||
/// <EFBFBD><EFBFBD><EFBFBD>Ի<EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ijһ<EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public event Action<ZCalendarDayItem> ChoiceDayEvent;
|
||||
/// <summary>
|
||||
/// 选择区间时间事件
|
||||
/// ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
|
||||
/// </summary>
|
||||
public event Action<ZCalendarDayItem, ZCalendarDayItem> RangeTimeEvent;
|
||||
/// <summary>
|
||||
/// 日历加载结束
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؽ<EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public event Action CompleteEvent;
|
||||
/// <summary>
|
||||
/// 获取当前选中的天对象
|
||||
/// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰѡ<EFBFBD>е<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public ZCalendarDayItem CrtTime { get; set; }
|
||||
/// <summary>
|
||||
|
|
@ -36,7 +36,7 @@ namespace ZTools
|
|||
/// </summary>
|
||||
private ZCalendarController zCalendarController;
|
||||
/// <summary>
|
||||
/// 入口
|
||||
/// <EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
private void Start()
|
||||
{
|
||||
|
|
@ -48,28 +48,28 @@ namespace ZTools
|
|||
pos = this.transform.localPosition
|
||||
};
|
||||
zCalendarController.Init();
|
||||
// 开启时自动初始化
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>
|
||||
if (zCalendarModel.awake2Init)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 按照现在时间初始化
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public void Init()
|
||||
{
|
||||
zCalendarController.InitDate(DateTime.Now);
|
||||
}
|
||||
/// <summary>
|
||||
/// 按照DateTime格式初始化日历
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>DateTime<EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public void Init(DateTime dateTime)
|
||||
{
|
||||
zCalendarController.InitDate(dateTime);
|
||||
}
|
||||
/// <summary>
|
||||
/// 按照YYYY-MM-DD格式初始化日历
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>YYYY-MM-DD<44><44>ʽ<EFBFBD><CABD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public void Init(string dateTime)
|
||||
{
|
||||
|
|
@ -77,14 +77,14 @@ namespace ZTools
|
|||
zCalendarController.InitDate(new DateTime(int.Parse(dateTimes[0]), int.Parse(dateTimes[1]), int.Parse(dateTimes[2])));
|
||||
}
|
||||
/// <summary>
|
||||
/// 显示弹窗
|
||||
/// <EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public void Show()
|
||||
{
|
||||
zCalendarController.Show();
|
||||
}
|
||||
/// <summary>
|
||||
/// 隐藏弹窗
|
||||
/// <EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public void Hide()
|
||||
{
|
||||
|
|
@ -92,10 +92,10 @@ namespace ZTools
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 切换时间
|
||||
/// <EFBFBD>л<EFBFBD>ʱ<EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
[Obsolete("事件触发器,请使用UpdateDateEvent获取切换月份时加载的时间对象")]
|
||||
[Obsolete("<EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>UpdateDateEvent<EFBFBD><EFBFBD>ȡ<EFBFBD>л<EFBFBD><EFBFBD>·<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")]
|
||||
public void UpdateDate(ZCalendarDayItem obj)
|
||||
{
|
||||
if (null != UpdateDateEvent)
|
||||
|
|
@ -104,9 +104,9 @@ namespace ZTools
|
|||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 日期点击
|
||||
/// <EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
[Obsolete("事件触发器,请使用ChoiceDayEvent获取当前选择的时间")]
|
||||
[Obsolete("<EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>ChoiceDayEvent<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰѡ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>")]
|
||||
public void DayClick(ZCalendarDayItem dayItem)
|
||||
{
|
||||
if (null != ChoiceDayEvent)
|
||||
|
|
@ -116,9 +116,9 @@ namespace ZTools
|
|||
CrtTime = dayItem;
|
||||
}
|
||||
/// <summary>
|
||||
/// 加载结束
|
||||
/// <EFBFBD><EFBFBD><EFBFBD>ؽ<EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
[Obsolete("事件触发器,请使用CompleteEvent获取日历加载完成事件")]
|
||||
[Obsolete("<EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>CompleteEvent<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>")]
|
||||
public void DateComplete()
|
||||
{
|
||||
if (null != CompleteEvent)
|
||||
|
|
@ -127,11 +127,11 @@ namespace ZTools
|
|||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 区间日期选择
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
/// <param name="firstDay"></param>
|
||||
/// <param name="secondDay"></param>
|
||||
[Obsolete("事件触发器,请使用RangeTimeEvent获取区间时间")]
|
||||
[Obsolete("<EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>RangeTimeEvent<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>")]
|
||||
public void RangeCalendar(ZCalendarDayItem firstDay, ZCalendarDayItem secondDay )
|
||||
{
|
||||
if (null != RangeTimeEvent)
|
||||
|
|
@ -139,10 +139,26 @@ namespace ZTools
|
|||
RangeTimeEvent.Invoke(firstDay, secondDay);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 组件销毁时清理资源
|
||||
/// </summary>
|
||||
private void OnDestroy()
|
||||
{
|
||||
// 清理事件订阅,避免内存泄漏
|
||||
UpdateDateEvent = null;
|
||||
ChoiceDayEvent = null;
|
||||
RangeTimeEvent = null;
|
||||
CompleteEvent = null;
|
||||
|
||||
// 清理引用
|
||||
zCalendarController = null;
|
||||
GC.Collect();
|
||||
zCalendarModel = null;
|
||||
CrtTime = null;
|
||||
|
||||
// 移除 GC.Collect() 调用
|
||||
// .NET 的垃圾回收器会自动管理内存,不需要手动调用 GC.Collect()
|
||||
// 频繁调用 GC.Collect() 会导致垃圾回收效率下降,影响应用程序性能
|
||||
// 如果有非托管资源需要释放,应该实现 IDisposable 接口,使用 using 语句确保资源释放
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -384,8 +384,10 @@ namespace RenderHeads.Media.AVProVideo.Editor
|
|||
EditorHelper.IMGUI.NoticeBox(MessageType.Warning, "Using this very large file inside StreamingAssets folder on Android isn't recommended. Deployments will be slow and mapping the file from the StreamingAssets JAR may cause storage and memory issues. We recommend loading from another folder on the device.");
|
||||
}
|
||||
}
|
||||
catch (System.Exception)
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
// 记录检查Android文件大小时发生的异常,便于调试和维护
|
||||
UnityEngine.Debug.LogWarning($"MediaPlayerEditor_Source: 检查Android文件大小时发生错误 - {ex.Message}\n文件路径: {fullPath}\n堆栈: {ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,8 +68,19 @@ public class ProcessScoreWindow : EditorWindow
|
|||
fontStyle = FontStyle.Bold
|
||||
};
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
// 记录初始化样式时的异常,便于调试和维护
|
||||
Debug.LogError($"ProcessScoreWindow初始化样式失败(参数错误): {e.Message}\n{e.StackTrace}");
|
||||
}
|
||||
catch (NullReferenceException e)
|
||||
{
|
||||
Debug.LogError($"ProcessScoreWindow初始化样式失败(空引用): {e.Message}\n{e.StackTrace}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// 记录初始化样式时的异常,便于调试和维护
|
||||
Debug.LogError($"ProcessScoreWindow初始化样式失败: {e.Message}\n{e.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -271,6 +282,14 @@ public class ProcessScoreWindow : EditorWindow
|
|||
{
|
||||
EditorGUILayout.HelpBox($"当前模式 '{processManager._currentMode}' 不存在", MessageType.Error);
|
||||
}
|
||||
catch (NullReferenceException ex)
|
||||
{
|
||||
EditorGUILayout.HelpBox($"发生错误(空引用): {ex.Message}", MessageType.Error);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
EditorGUILayout.HelpBox($"发生错误(无效操作): {ex.Message}", MessageType.Error);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
EditorGUILayout.HelpBox($"发生错误: {ex.Message}", MessageType.Error);
|
||||
|
|
@ -316,6 +335,18 @@ public class ProcessScoreWindow : EditorWindow
|
|||
|
||||
Repaint(); // 刷新界面
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
EditorUtility.DisplayDialog("跳转取消", $"跳转操作被取消: {ex.Message}", "确定");
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
EditorUtility.DisplayDialog("跳转失败", $"跳转过程中发生错误(无效操作): {ex.Message}", "确定");
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
EditorUtility.DisplayDialog("跳转失败", $"跳转过程中发生错误(参数错误): {ex.Message}", "确定");
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
EditorUtility.DisplayDialog("跳转失败", $"跳转过程中发生错误: {ex.Message}", "确定");
|
||||
|
|
|
|||
|
|
@ -15,29 +15,107 @@ namespace MotionFramework.Utility
|
|||
return result.ToLower();
|
||||
}
|
||||
|
||||
#region SHA1
|
||||
#region SHA1 [已废弃 - 使用SHA256替代]
|
||||
/// <summary>
|
||||
/// 获取字符串的Hash值
|
||||
/// 获取字符串的Hash值(已废弃,请使用StringSHA256)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// SHA1算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。
|
||||
/// </remarks>
|
||||
[System.Obsolete("SHA1算法不安全,请使用StringSHA256方法", false)]
|
||||
public static string StringSHA1(string str)
|
||||
{
|
||||
byte[] buffer = Encoding.UTF8.GetBytes(str);
|
||||
return BytesSHA1(buffer);
|
||||
// 已替换为SHA256实现以提高安全性
|
||||
return StringSHA256(str);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件的Hash值
|
||||
/// 获取文件的Hash值(已废弃,请使用FileSHA256)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// SHA1算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。
|
||||
/// </remarks>
|
||||
[System.Obsolete("SHA1算法不安全,请使用FileSHA256方法", false)]
|
||||
public static string FileSHA1(string filePath)
|
||||
{
|
||||
// 已替换为SHA256实现以提高安全性
|
||||
return FileSHA256(filePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据流的Hash值(已废弃,请使用StreamSHA256)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// SHA1算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。
|
||||
/// </remarks>
|
||||
[System.Obsolete("SHA1算法不安全,请使用StreamSHA256方法", false)]
|
||||
public static string StreamSHA1(Stream stream)
|
||||
{
|
||||
// 已替换为SHA256实现以提高安全性
|
||||
return StreamSHA256(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取字节数组的Hash值(已废弃,请使用BytesSHA256)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// SHA1算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。
|
||||
/// </remarks>
|
||||
[System.Obsolete("SHA1算法不安全,请使用BytesSHA256方法", false)]
|
||||
public static string BytesSHA1(byte[] buffer)
|
||||
{
|
||||
// 已替换为SHA256实现以提高安全性
|
||||
return BytesSHA256(buffer);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SHA256 [推荐使用]
|
||||
/// <summary>
|
||||
/// 获取字符串的SHA256哈希值(推荐使用)
|
||||
/// </summary>
|
||||
/// <param name="str">要计算哈希的字符串</param>
|
||||
/// <returns>SHA256哈希值的十六进制字符串</returns>
|
||||
public static string StringSHA256(string str)
|
||||
{
|
||||
byte[] buffer = Encoding.UTF8.GetBytes(str);
|
||||
return BytesSHA256(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件的SHA256哈希值(推荐使用)
|
||||
/// </summary>
|
||||
/// <param name="filePath">文件路径</param>
|
||||
/// <returns>SHA256哈希值的十六进制字符串,如果文件不存在或读取失败则返回空字符串</returns>
|
||||
public static string FileSHA256(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return StreamSHA1(fs);
|
||||
return StreamSHA256(fs);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
MotionLog.Exception($"文件不存在: {filePath}\n{e}");
|
||||
return string.Empty;
|
||||
}
|
||||
catch (DirectoryNotFoundException e)
|
||||
{
|
||||
MotionLog.Exception($"目录不存在: {filePath}\n{e}");
|
||||
return string.Empty;
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
MotionLog.Exception($"访问被拒绝,权限不足: {filePath}\n{e}");
|
||||
return string.Empty;
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
MotionLog.Exception($"参数错误: {filePath}\n{e}");
|
||||
return string.Empty;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
MotionLog.Exception(e.ToString());
|
||||
return string.Empty;
|
||||
|
|
@ -45,13 +123,18 @@ namespace MotionFramework.Utility
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据流的Hash值
|
||||
/// 获取数据流的SHA256哈希值(推荐使用)
|
||||
/// </summary>
|
||||
public static string StreamSHA1(Stream stream)
|
||||
/// <param name="stream">要计算哈希的数据流</param>
|
||||
/// <returns>SHA256哈希值的十六进制字符串</returns>
|
||||
/// <remarks>
|
||||
/// 使用SHA256算法,生成256位的散列码,提供更高的安全性
|
||||
/// </remarks>
|
||||
public static string StreamSHA256(Stream stream)
|
||||
{
|
||||
// 说明:创建的是SHA1类的实例,生成的是160位的散列码
|
||||
// 使用SHA256算法替代不安全的SHA1,提供更高的安全性
|
||||
// 使用 using 语句确保资源正确释放,防止资源泄漏
|
||||
using (HashAlgorithm hash = HashAlgorithm.Create())
|
||||
using (SHA256 hash = SHA256.Create())
|
||||
{
|
||||
byte[] hashBytes = hash.ComputeHash(stream);
|
||||
return ToString(hashBytes);
|
||||
|
|
@ -59,13 +142,18 @@ namespace MotionFramework.Utility
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取字节数组的Hash值
|
||||
/// 获取字节数组的SHA256哈希值(推荐使用)
|
||||
/// </summary>
|
||||
public static string BytesSHA1(byte[] buffer)
|
||||
/// <param name="buffer">要计算哈希的字节数组</param>
|
||||
/// <returns>SHA256哈希值的十六进制字符串</returns>
|
||||
/// <remarks>
|
||||
/// 使用SHA256算法,生成256位的散列码,提供更高的安全性
|
||||
/// </remarks>
|
||||
public static string BytesSHA256(byte[] buffer)
|
||||
{
|
||||
// 说明:创建的是SHA1类的实例,生成的是160位的散列码
|
||||
// 使用SHA256算法替代不安全的SHA1,提供更高的安全性
|
||||
// 使用 using 语句确保资源正确释放,防止资源泄漏
|
||||
using (HashAlgorithm hash = HashAlgorithm.Create())
|
||||
using (SHA256 hash = SHA256.Create())
|
||||
{
|
||||
byte[] hashBytes = hash.ComputeHash(buffer);
|
||||
return ToString(hashBytes);
|
||||
|
|
@ -73,59 +161,57 @@ namespace MotionFramework.Utility
|
|||
}
|
||||
#endregion
|
||||
|
||||
#region MD5
|
||||
#region MD5 [已废弃 - 使用SHA256替代]
|
||||
/// <summary>
|
||||
/// 获取字符串的MD5
|
||||
/// 获取字符串的MD5(已废弃,请使用StringSHA256)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// MD5算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。
|
||||
/// </remarks>
|
||||
[System.Obsolete("MD5算法不安全,请使用StringSHA256方法", false)]
|
||||
public static string StringMD5(string str)
|
||||
{
|
||||
byte[] buffer = Encoding.UTF8.GetBytes(str);
|
||||
return BytesMD5(buffer);
|
||||
// 已替换为SHA256实现以提高安全性
|
||||
return StringSHA256(str);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件的MD5
|
||||
/// 获取文件的MD5(已废弃,请使用FileSHA256)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// MD5算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。
|
||||
/// </remarks>
|
||||
[System.Obsolete("MD5算法不安全,请使用FileSHA256方法", false)]
|
||||
public static string FileMD5(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return StreamMD5(fs);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MotionLog.Exception(e.ToString());
|
||||
return string.Empty;
|
||||
}
|
||||
// 已替换为SHA256实现以提高安全性
|
||||
return FileSHA256(filePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据流的MD5
|
||||
/// 获取数据流的MD5(已废弃,请使用StreamSHA256)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// MD5算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。
|
||||
/// </remarks>
|
||||
[System.Obsolete("MD5算法不安全,请使用StreamSHA256方法", false)]
|
||||
public static string StreamMD5(Stream stream)
|
||||
{
|
||||
// 使用 using 语句确保资源正确释放,防止资源泄漏
|
||||
using (MD5 md5 = MD5.Create())
|
||||
{
|
||||
byte[] hashBytes = md5.ComputeHash(stream);
|
||||
return ToString(hashBytes);
|
||||
}
|
||||
// 已替换为SHA256实现以提高安全性
|
||||
return StreamSHA256(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取字节数组的MD5
|
||||
/// 获取字节数组的MD5(已废弃,请使用BytesSHA256)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// MD5算法已被认为不安全,已替换为SHA256实现。保留此方法仅为向后兼容。
|
||||
/// </remarks>
|
||||
[System.Obsolete("MD5算法不安全,请使用BytesSHA256方法", false)]
|
||||
public static string BytesMD5(byte[] buffer)
|
||||
{
|
||||
// 使用 using 语句确保资源正确释放,防止资源泄漏
|
||||
using (MD5 md5 = MD5.Create())
|
||||
{
|
||||
byte[] hashBytes = md5.ComputeHash(buffer);
|
||||
return ToString(hashBytes);
|
||||
}
|
||||
// 已替换为SHA256实现以提高安全性
|
||||
return BytesSHA256(buffer);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
|
@ -151,7 +237,27 @@ namespace MotionFramework.Utility
|
|||
return StreamCRC32(fs);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
MotionLog.Exception($"文件不存在: {filePath}\n{e}");
|
||||
return string.Empty;
|
||||
}
|
||||
catch (DirectoryNotFoundException e)
|
||||
{
|
||||
MotionLog.Exception($"目录不存在: {filePath}\n{e}");
|
||||
return string.Empty;
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
MotionLog.Exception($"访问被拒绝,权限不足: {filePath}\n{e}");
|
||||
return string.Empty;
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
MotionLog.Exception($"参数错误: {filePath}\n{e}");
|
||||
return string.Empty;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
MotionLog.Exception(e.ToString());
|
||||
return string.Empty;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
|
@ -33,7 +34,32 @@ namespace Framework.Utils
|
|||
return await reader.ReadToEndAsync();
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
Debug.LogError($"读取文件失败:文件不存在: {filePath}\n{ex}");
|
||||
return null;
|
||||
}
|
||||
catch (DirectoryNotFoundException ex)
|
||||
{
|
||||
Debug.LogError($"读取文件失败:目录不存在: {filePath}\n{ex}");
|
||||
return null;
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
Debug.LogError($"读取文件失败:访问被拒绝,权限不足: {filePath}\n{ex}");
|
||||
return null;
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
Debug.LogError($"读取文件失败:参数错误: {filePath}\n{ex}");
|
||||
return null;
|
||||
}
|
||||
catch (PathTooLongException ex)
|
||||
{
|
||||
Debug.LogError($"读取文件失败:文件路径过长: {filePath}\n{ex}");
|
||||
return null;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Debug.LogError($"读取文件失败: {filePath}\n{ex}");
|
||||
return null;
|
||||
|
|
@ -66,7 +92,27 @@ namespace Framework.Utils
|
|||
|
||||
return true;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
catch (DirectoryNotFoundException ex)
|
||||
{
|
||||
Debug.LogError($"写入文件失败:目录不存在: {filePath}\n{ex}");
|
||||
return false;
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
Debug.LogError($"写入文件失败:访问被拒绝,权限不足: {filePath}\n{ex}");
|
||||
return false;
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
Debug.LogError($"写入文件失败:参数错误: {filePath}\n{ex}");
|
||||
return false;
|
||||
}
|
||||
catch (PathTooLongException ex)
|
||||
{
|
||||
Debug.LogError($"写入文件失败:文件路径过长: {filePath}\n{ex}");
|
||||
return false;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Debug.LogError($"写入文件失败: {filePath}\n{ex}");
|
||||
return false;
|
||||
|
|
@ -100,7 +146,32 @@ namespace Framework.Utils
|
|||
|
||||
return false;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
Debug.LogError($"删除文件失败:文件不存在: {filePath}\n{ex}");
|
||||
return false;
|
||||
}
|
||||
catch (DirectoryNotFoundException ex)
|
||||
{
|
||||
Debug.LogError($"删除文件失败:目录不存在: {filePath}\n{ex}");
|
||||
return false;
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
Debug.LogError($"删除文件失败:访问被拒绝,权限不足: {filePath}\n{ex}");
|
||||
return false;
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
Debug.LogError($"删除文件失败:参数错误: {filePath}\n{ex}");
|
||||
return false;
|
||||
}
|
||||
catch (PathTooLongException ex)
|
||||
{
|
||||
Debug.LogError($"删除文件失败:文件路径过长: {filePath}\n{ex}");
|
||||
return false;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Debug.LogError($"删除文件失败: {filePath}\n{ex}");
|
||||
return false;
|
||||
|
|
@ -131,11 +202,27 @@ namespace Framework.Utils
|
|||
|
||||
return true;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
Debug.LogError($"打开文件失败: {filePath}\n{ex}");
|
||||
Debug.LogError($"打开文件失败:文件不存在: {filePath}\n{ex}");
|
||||
return false;
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
Debug.LogError($"打开文件失败:参数错误: {filePath}\n{ex}");
|
||||
return false;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
Debug.LogError($"打开文件失败:无效操作: {filePath}\n{ex}");
|
||||
return false;
|
||||
}
|
||||
catch (System.ComponentModel.Win32Exception ex)
|
||||
{
|
||||
Debug.LogError($"打开文件失败:系统错误: {filePath}\n{ex}");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -68,7 +68,8 @@ namespace Cysharp.Threading.Tasks.Editor
|
|||
public static bool EnableStackTrace => TaskTracker.EditorEnableState.EnableStackTrace;
|
||||
static readonly GUIContent EnableAutoReloadHeadContent = EditorGUIUtility.TrTextContent("Enable AutoReload", "Reload automatically.", (Texture)null);
|
||||
static readonly GUIContent ReloadHeadContent = EditorGUIUtility.TrTextContent("Reload", "Reload View.", (Texture)null);
|
||||
static readonly GUIContent GCHeadContent = EditorGUIUtility.TrTextContent("GC.Collect", "Invoke GC.Collect.", (Texture)null);
|
||||
// GC.Collect 按钮已移除,避免频繁强制垃圾回收影响性能
|
||||
// static readonly GUIContent GCHeadContent = EditorGUIUtility.TrTextContent("GC.Collect", "Invoke GC.Collect.", (Texture)null);
|
||||
static readonly GUIContent EnableTrackingHeadContent = EditorGUIUtility.TrTextContent("Enable Tracking", "Start to track async/await UniTask. Performance impact: low", (Texture)null);
|
||||
static readonly GUIContent EnableStackTraceHeadContent = EditorGUIUtility.TrTextContent("Enable StackTrace", "Capture StackTrace when task is started. Performance impact: high", (Texture)null);
|
||||
|
||||
|
|
@ -102,10 +103,14 @@ namespace Cysharp.Threading.Tasks.Editor
|
|||
Repaint();
|
||||
}
|
||||
|
||||
if (GUILayout.Button(GCHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption))
|
||||
{
|
||||
GC.Collect(0);
|
||||
}
|
||||
// 移除 GC.Collect() 调用,避免频繁强制垃圾回收影响性能
|
||||
// .NET 的垃圾回收器会自动管理内存,不需要手动调用 GC.Collect()
|
||||
// 如果确实需要释放内存,应使用 using 语句或 IDisposable 接口释放非托管资源
|
||||
// 注意:此按钮已移除,如需调试内存问题,请使用 Unity Profiler
|
||||
// if (GUILayout.Button(GCHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption))
|
||||
// {
|
||||
// GC.Collect(0);
|
||||
// }
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndVertical();
|
||||
|
|
|
|||
|
|
@ -99,6 +99,19 @@ namespace Cysharp.Threading.Tasks
|
|||
awaiter.GetResult();
|
||||
completionSource.TrySetResult();
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
|
|
@ -218,6 +231,19 @@ namespace Cysharp.Threading.Tasks
|
|||
var result = awaiter.GetResult();
|
||||
completionSource.TrySetResult(result);
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
|
|
|
|||
|
|
@ -188,7 +188,11 @@ namespace Cysharp.Threading.Tasks.Internal
|
|||
{
|
||||
unhandledExceptionCallback(ex);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception callbackEx)
|
||||
{
|
||||
// 记录异常回调本身也抛出异常的情况,避免异常被静默忽略
|
||||
Debug.LogError($"PlayerLoopRunner: 异常回调函数执行失败 - {callbackEx.Message}\n原始异常: {ex.Message}\n回调异常堆栈: {callbackEx.StackTrace}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -223,7 +227,11 @@ namespace Cysharp.Threading.Tasks.Internal
|
|||
{
|
||||
unhandledExceptionCallback(ex);
|
||||
}
|
||||
catch { }
|
||||
catch (Exception callbackEx)
|
||||
{
|
||||
// 记录异常回调本身也抛出异常的情况,避免异常被静默忽略
|
||||
Debug.LogError($"PlayerLoopRunner: 异常回调函数执行失败 - {callbackEx.Message}\n原始异常: {ex.Message}\n回调异常堆栈: {callbackEx.StackTrace}");
|
||||
}
|
||||
continue; // next j
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
goto CONTINUE;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
|
|
@ -217,6 +233,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
completionSource.TrySetResult(result);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -109,6 +109,20 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
await task;
|
||||
goto DONE;
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
Volatile.Write(ref state, -2);
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
Volatile.Write(ref state, -2);
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
Volatile.Write(ref state, -2);
|
||||
|
|
|
|||
|
|
@ -175,6 +175,20 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
goto DONE;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
state = -2;
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
state = -2;
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
state = -2;
|
||||
|
|
@ -319,6 +333,20 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
goto DONE;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
state = -2;
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
state = -2;
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
state = -2;
|
||||
|
|
@ -477,6 +505,20 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
goto DONE;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
state = -2;
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
state = -2;
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
state = -2;
|
||||
|
|
@ -635,6 +677,20 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
goto DONE;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
state = -2;
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
state = -2;
|
||||
completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
state = -2;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,16 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
}
|
||||
trigger.SetCompleted();
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为错误状态
|
||||
trigger.SetError(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
trigger.SetError(ex);
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
trigger.SetError(ex);
|
||||
|
|
|
|||
|
|
@ -322,6 +322,29 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
}
|
||||
onCompleted();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// 操作被取消,直接返回,不触发错误回调
|
||||
return;
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
{
|
||||
UniTaskScheduler.PublishUnobservedTaskException(ex);
|
||||
return;
|
||||
}
|
||||
onError(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
{
|
||||
UniTaskScheduler.PublishUnobservedTaskException(ex);
|
||||
return;
|
||||
}
|
||||
onError(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
|
|
@ -330,8 +353,6 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
return;
|
||||
}
|
||||
|
||||
if (ex is OperationCanceledException) return;
|
||||
|
||||
onError(ex);
|
||||
}
|
||||
finally
|
||||
|
|
@ -361,6 +382,29 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
}
|
||||
onCompleted();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// 操作被取消,直接返回,不触发错误回调
|
||||
return;
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
{
|
||||
UniTaskScheduler.PublishUnobservedTaskException(ex);
|
||||
return;
|
||||
}
|
||||
onError(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
{
|
||||
UniTaskScheduler.PublishUnobservedTaskException(ex);
|
||||
return;
|
||||
}
|
||||
onError(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
|
|
@ -369,8 +413,6 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
return;
|
||||
}
|
||||
|
||||
if (ex is OperationCanceledException) return;
|
||||
|
||||
onError(ex);
|
||||
}
|
||||
finally
|
||||
|
|
@ -400,6 +442,29 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
}
|
||||
onCompleted();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// 操作被取消,直接返回,不触发错误回调
|
||||
return;
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
{
|
||||
UniTaskScheduler.PublishUnobservedTaskException(ex);
|
||||
return;
|
||||
}
|
||||
onError(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
{
|
||||
UniTaskScheduler.PublishUnobservedTaskException(ex);
|
||||
return;
|
||||
}
|
||||
onError(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
|
|
@ -408,8 +473,6 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
return;
|
||||
}
|
||||
|
||||
if (ex is OperationCanceledException) return;
|
||||
|
||||
onError(ex);
|
||||
}
|
||||
finally
|
||||
|
|
@ -439,10 +502,18 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
}
|
||||
observer.OnCompleted();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// 操作被取消,直接返回,不触发错误回调
|
||||
return;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
observer.OnError(ex);
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex is OperationCanceledException) return;
|
||||
|
||||
observer.OnError(ex);
|
||||
}
|
||||
finally
|
||||
|
|
@ -472,6 +543,29 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
}
|
||||
onCompleted();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// 操作被取消,直接返回,不触发错误回调
|
||||
return;
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
{
|
||||
UniTaskScheduler.PublishUnobservedTaskException(ex);
|
||||
return;
|
||||
}
|
||||
onError(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
{
|
||||
UniTaskScheduler.PublishUnobservedTaskException(ex);
|
||||
return;
|
||||
}
|
||||
onError(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
|
|
@ -480,8 +574,6 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
return;
|
||||
}
|
||||
|
||||
if (ex is OperationCanceledException) return;
|
||||
|
||||
onError(ex);
|
||||
}
|
||||
finally
|
||||
|
|
@ -511,6 +603,29 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
}
|
||||
onCompleted();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// 操作被取消,直接返回,不触发错误回调
|
||||
return;
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
{
|
||||
UniTaskScheduler.PublishUnobservedTaskException(ex);
|
||||
return;
|
||||
}
|
||||
onError(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
{
|
||||
UniTaskScheduler.PublishUnobservedTaskException(ex);
|
||||
return;
|
||||
}
|
||||
onError(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (onError == NopError)
|
||||
|
|
@ -519,8 +634,6 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
return;
|
||||
}
|
||||
|
||||
if (ex is OperationCanceledException) return;
|
||||
|
||||
onError(ex);
|
||||
}
|
||||
finally
|
||||
|
|
|
|||
|
|
@ -143,6 +143,25 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
return true;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
completionSource.TrySetException(ex);
|
||||
DisposeAsync().Forget();
|
||||
return false;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
DisposeAsync().Forget();
|
||||
return false;
|
||||
}
|
||||
catch (NullReferenceException ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
DisposeAsync().Forget();
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
|
|
@ -276,6 +295,25 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
return true;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
completionSource.TrySetException(ex);
|
||||
DisposeAsync().Forget();
|
||||
return false;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
DisposeAsync().Forget();
|
||||
return false;
|
||||
}
|
||||
catch (NullReferenceException ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
DisposeAsync().Forget();
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
|
|
|
|||
|
|
@ -125,6 +125,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
{
|
||||
self.secondAwaiter = self.secondEnumerator.MoveNextAsync().GetAwaiter();
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
self.completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
|
|
@ -159,6 +175,19 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
{
|
||||
self.Current = self.resultSelector(self.firstEnumerator.Current, self.secondEnumerator.Current);
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
self.completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (ArgumentNullException ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
|
|
@ -279,6 +308,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
{
|
||||
self.secondAwaiter = self.secondEnumerator.MoveNextAsync().GetAwaiter();
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
self.completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
|
|
@ -321,6 +366,19 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
self.resultAwaiter.SourceOnCompleted(resultAwaitCoreDelegate, self);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
self.completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (ArgumentNullException ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
|
|
@ -451,6 +509,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
{
|
||||
self.secondAwaiter = self.secondEnumerator.MoveNextAsync().GetAwaiter();
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
self.completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
|
|
@ -493,6 +567,19 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||
self.resultAwaiter.SourceOnCompleted(resultAwaitCoreDelegate, self);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,设置为取消状态
|
||||
self.completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (ArgumentNullException ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
|
|
|
|||
|
|
@ -299,7 +299,11 @@ namespace Cysharp.Threading.Tasks
|
|||
{
|
||||
applicationDataPath = Application.dataPath;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 记录初始化Application.dataPath时发生的异常,使用空字符串作为默认值
|
||||
UnityEngine.Debug.LogWarning($"PlayerLoopHelper: 无法获取Application.dataPath,使用空字符串作为默认值。错误: {ex.Message}\n堆栈: {ex.StackTrace}");
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR && UNITY_2019_3_OR_NEWER
|
||||
// When domain reload is disabled, re-initialization is required when entering play mode;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,11 @@ namespace Cysharp.Threading.Tasks
|
|||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 记录读取环境变量失败的情况,使用默认值MaxPoolSize = int.MaxValue
|
||||
UnityEngine.Debug.LogWarning($"TaskPool: 无法读取环境变量 UNITASK_MAX_POOLSIZE,使用默认值 int.MaxValue。错误: {ex.Message}");
|
||||
}
|
||||
|
||||
MaxPoolSize = int.MaxValue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,22 @@ namespace Cysharp.Threading.Tasks
|
|||
{
|
||||
h.OnNext(value);
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,记录错误
|
||||
LogError(ex);
|
||||
Remove(h);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
LogError(ex);
|
||||
Remove(h);
|
||||
}
|
||||
catch (NullReferenceException ex)
|
||||
{
|
||||
LogError(ex);
|
||||
Remove(h);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogError(ex);
|
||||
|
|
@ -84,6 +100,19 @@ namespace Cysharp.Threading.Tasks
|
|||
{
|
||||
h.OnCanceled(cancellationToken);
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,记录错误
|
||||
LogError(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
LogError(ex);
|
||||
}
|
||||
catch (NullReferenceException ex)
|
||||
{
|
||||
LogError(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogError(ex);
|
||||
|
|
@ -118,6 +147,19 @@ namespace Cysharp.Threading.Tasks
|
|||
{
|
||||
h.OnCompleted();
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,记录错误
|
||||
LogError(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
LogError(ex);
|
||||
}
|
||||
catch (NullReferenceException ex)
|
||||
{
|
||||
LogError(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogError(ex);
|
||||
|
|
@ -152,6 +194,19 @@ namespace Cysharp.Threading.Tasks
|
|||
{
|
||||
h.OnError(exception);
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
// 操作被取消,记录错误
|
||||
LogError(ex);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
LogError(ex);
|
||||
}
|
||||
catch (NullReferenceException ex)
|
||||
{
|
||||
LogError(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogError(ex);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -113,8 +113,10 @@ namespace Cysharp.Threading.Tasks
|
|||
UniTaskScheduler.PublishUnobservedTaskException(e.GetException().SourceException);
|
||||
}
|
||||
}
|
||||
catch
|
||||
catch (Exception reportEx)
|
||||
{
|
||||
// 记录报告未处理异常时发生的错误,避免异常被静默忽略
|
||||
UnityEngine.Debug.LogError($"UniTaskCompletionSource: 报告未处理的异常时发生错误 - {reportEx.Message}\n堆栈: {reportEx.StackTrace}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ using Framework.Manager;
|
|||
|
||||
public static class InterfaceManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件读取的最大大小限制(10MB),用于防止拒绝服务攻击
|
||||
/// </summary>
|
||||
private const long MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024; // 10MB
|
||||
|
||||
/// <summary>
|
||||
/// 查找物体
|
||||
/// </summary>
|
||||
|
|
@ -115,7 +120,7 @@ public static class InterfaceManager
|
|||
#region
|
||||
|
||||
/// <summary>
|
||||
/// 读取数据 PC端
|
||||
/// 读取数据 PC端(已添加安全验证,防止拒绝服务攻击)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="fileName"></param>
|
||||
|
|
@ -133,28 +138,129 @@ public static class InterfaceManager
|
|||
{
|
||||
return new T();
|
||||
}
|
||||
//获取json字符串
|
||||
string jsonStr = File.ReadAllText(path);
|
||||
|
||||
//
|
||||
T data = new T();
|
||||
//反序列
|
||||
switch (type)
|
||||
try
|
||||
{
|
||||
case JsonType.LitJson:
|
||||
data = JsonMapper.ToObject<T>(jsonStr);
|
||||
break;
|
||||
case JsonType.JsonUtility:
|
||||
data = JsonUtility.FromJson<T>(jsonStr);
|
||||
break;
|
||||
// 验证文件大小,防止拒绝服务攻击
|
||||
FileInfo fileInfo = new FileInfo(path);
|
||||
if (fileInfo.Length > MAX_FILE_SIZE_BYTES)
|
||||
{
|
||||
Debug.LogError($"LoadData: 文件大小超过限制 ({fileInfo.Length} 字节 > {MAX_FILE_SIZE_BYTES} 字节) - {path}");
|
||||
return new T();
|
||||
}
|
||||
|
||||
// 验证路径是否为文件(而非目录)
|
||||
if ((fileInfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
|
||||
{
|
||||
Debug.LogError($"LoadData: 路径指向目录而非文件 - {path}");
|
||||
return new T();
|
||||
}
|
||||
|
||||
//获取json字符串
|
||||
string jsonStr = File.ReadAllText(path);
|
||||
|
||||
//
|
||||
T data = new T();
|
||||
//反序列
|
||||
switch (type)
|
||||
{
|
||||
case JsonType.LitJson:
|
||||
data = JsonMapper.ToObject<T>(jsonStr);
|
||||
break;
|
||||
case JsonType.JsonUtility:
|
||||
data = JsonUtility.FromJson<T>(jsonStr);
|
||||
break;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
Debug.LogError($"LoadData: 访问文件时权限不足 - {path}, 错误: {ex.Message}");
|
||||
return new T();
|
||||
}
|
||||
catch (System.Security.SecurityException ex)
|
||||
{
|
||||
Debug.LogError($"LoadData: 安全异常 - {path}, 错误: {ex.Message}");
|
||||
return new T();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Debug.LogError($"LoadData: IO异常 - {path}, 错误: {ex.Message}");
|
||||
return new T();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"LoadData: 读取文件时发生未知错误 - {path}, 错误: {ex.Message}");
|
||||
return new T();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 读取本地文本文件内容(已添加安全验证,防止拒绝服务攻击)
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <returns>文件内容字符串,如果文件不存在、过大或读取失败则返回null</returns>
|
||||
public static string GetLocalTxt(string path)
|
||||
{
|
||||
using (System.IO.StreamReader reader = new System.IO.StreamReader(path)) { return reader.ReadToEnd(); }
|
||||
// 验证路径是否为空
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
Debug.LogError("GetLocalTxt: 文件路径为空");
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 验证文件是否存在
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
Debug.LogWarning($"GetLocalTxt: 文件不存在 - {path}");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 验证文件大小,防止拒绝服务攻击
|
||||
FileInfo fileInfo = new FileInfo(path);
|
||||
if (fileInfo.Length > MAX_FILE_SIZE_BYTES)
|
||||
{
|
||||
Debug.LogError($"GetLocalTxt: 文件大小超过限制 ({fileInfo.Length} 字节 > {MAX_FILE_SIZE_BYTES} 字节) - {path}");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 验证路径是否为文件(而非目录)
|
||||
if ((fileInfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
|
||||
{
|
||||
Debug.LogError($"GetLocalTxt: 路径指向目录而非文件 - {path}");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 安全读取文件内容
|
||||
using (System.IO.StreamReader reader = new System.IO.StreamReader(path))
|
||||
{
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
Debug.LogError($"GetLocalTxt: 访问文件时权限不足 - {path}, 错误: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
catch (System.Security.SecurityException ex)
|
||||
{
|
||||
Debug.LogError($"GetLocalTxt: 安全异常 - {path}, 错误: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Debug.LogError($"GetLocalTxt: IO异常 - {path}, 错误: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"GetLocalTxt: 读取文件时发生未知错误 - {path}, 错误: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerator GetBytes(string url, Action<byte[]> callback)
|
||||
|
|
|
|||
Loading…
Reference in New Issue