新增日志输出模式,规范写法
parent
b74e1634ee
commit
bc6b4e5ab0
|
@ -4,10 +4,12 @@ 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)
|
||||
{
|
||||
|
@ -21,8 +23,8 @@ unsafe
|
|||
(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,
|
||||
}
|
|
@ -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,20 +66,20 @@ 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")]
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue