新增日志输出模式,规范写法

master
Cal 2024-12-09 10:40:33 +08:00
parent b74e1634ee
commit bc6b4e5ab0
2 changed files with 65 additions and 30 deletions

View File

@ -4,11 +4,13 @@ using System.Runtime.InteropServices;
unsafe
{
Console.WriteLine(1);
SetLogImmediately(true);
SetLogOutputMode(LogMode.Manual);
SetLogInfo(& LogInfo);
SetLogError(& LogError);
TimeProvider.System.CreateTimer(Callback, null, TimeSpan.FromMilliseconds(16), TimeSpan.FromMilliseconds(16));
//Manual 才需要这个手动调用
//TimeProvider.System.CreateTimer(Callback, null, TimeSpan.FromMilliseconds(16), TimeSpan.FromMilliseconds(16));
void Callback(object? state)
{
Tick();
@ -20,9 +22,9 @@ unsafe
(char*)Unsafe.AsPointer(ref Unsafe.AsRef(in "C:\\A".GetPinnableReference())),
(char*)Unsafe.AsPointer(ref Unsafe.AsRef(in "C:\\B".GetPinnableReference())));
Console.ReadKey();
[DllImport("FileUtilsCs.dll", EntryPoint = "SetLogImmediately")]
static extern void SetLogImmediately(bool value);
[DllImport("FileUtilsCs.dll", EntryPoint = "SetLogOutputMode")]
static extern void SetLogOutputMode([MarshalAs(UnmanagedType.I4)]LogMode value);
[DllImport("FileUtilsCs.dll", EntryPoint = "TestLog")]
static extern void TestLog();
@ -47,4 +49,15 @@ unsafe
var addrOfPinnedObject = new string((char*)obj);
System.Console.WriteLine(addrOfPinnedObject);
}
}
enum LogMode
{
//自动
Auto,
//立即输出
Immediate,
//手动Tick
Manual,
}

View File

@ -1,41 +1,64 @@
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace FileUtilsCs;
public class EntryPoints
enum LogMode
{
//自动
Auto,
//立即输出
Immediate,
//手动Tick
Manual,
}
public static class EntryPoints
{
internal static Action<string>? logInfoAction;
internal static Action<string>? logErrorAction;
internal static bool logImmediately = false;
internal static LogMode mode = LogMode.Auto;
static ConcurrentQueue<string> _logQueue = new ConcurrentQueue<string>();
static ConcurrentQueue<string> _logInfoQueue = new ConcurrentQueue<string>();
static ConcurrentQueue<string> _logErrorQueue = new ConcurrentQueue<string>();
[UnmanagedCallersOnly(EntryPoint = "Tick")]
static void Tick()
static EntryPoints()
{
TimeProvider.System.CreateTimer(LogCallBack, null, TimeSpan.FromMilliseconds(0), TimeSpan.FromMilliseconds(16));
}
private static void LogCallBack(object? state)
{
if (mode == LogMode.Auto)
TickLog();
}
private static void TickLog()
{
if (logImmediately)
return;
if (_logErrorQueue.TryDequeue(out var error))
{
logErrorAction?.Invoke(error);
}
_logErrorQueue.Clear();
if (_logQueue.TryDequeue(out var message))
if (_logInfoQueue.TryDequeue(out var message))
{
logInfoAction?.Invoke(message);
}
}
_logQueue.Clear();
[UnmanagedCallersOnly(EntryPoint = "Tick")]
static void Tick()
{
if (mode != LogMode.Manual)
return;
TickLog();
}
public static void LogError(string message)
{
if (logImmediately)
if (mode == LogMode.Immediate)
logErrorAction?.Invoke(message);
else
_logErrorQueue.Enqueue(message);
@ -43,22 +66,22 @@ public class EntryPoints
public static void Log(string message)
{
if (logImmediately)
if (mode == LogMode.Immediate)
logInfoAction?.Invoke(message);
else
_logQueue.Enqueue(message);
_logInfoQueue.Enqueue(message);
}
/// <summary>
/// 立即输出日志
/// 设置日志输出类型
/// </summary>
/// <param name="value"></param>
[UnmanagedCallersOnly(EntryPoint = "SetLogImmediately")]
public static void SetLogImmediately(bool value)
/// <param name="mode"></param>
[UnmanagedCallersOnly(EntryPoint = "SetLogOutputMode")]
public static void SetLogOutputMode(int mode = 0)
{
logImmediately = value;
EntryPoints.mode = (LogMode)mode;
}
[UnmanagedCallersOnly(EntryPoint = "SetLogInfo")]
public static unsafe void SetLogInfo(delegate* managed<nint, void> logAction)
{
@ -106,9 +129,9 @@ public class EntryPoints
try
{
if (isRoot && !Directory.Exists(srcRootPath))
throw new Exception($"srcRootPath : {srcRootPath} not exists!");
throw new Win32Exception($"srcRootPath : {srcRootPath} not exists!");
if (isRoot && !Directory.Exists(destRootPath))
throw new Exception($"srcRootPath : {destRootPath} not exists!");
throw new Win32Exception($"srcRootPath : {destRootPath} not exists!");
if (Path.GetFullPath(srcRootPath) == Path.GetFullPath(destRootPath))
return;
srcRootPath = srcRootPath[srcRootPath.Length - 1] != Path.DirectorySeparatorChar ? srcRootPath + Path.DirectorySeparatorChar : srcRootPath;
@ -128,8 +151,7 @@ public class EntryPoints
var destDirectoryInfo = new FileInfo(destFileFullName).Directory;
if (destDirectoryInfo == null)
{
LogError($"destDirectoryInfo is null where path is :{destFileFullName}");
return;
throw new IOException($"destDirectoryInfo is null where path is :{destFileFullName}");
}
if (!destDirectoryInfo.Exists)