Implement Logging
Fix Invocation Exceptions In Some Animated Form Controls Remove Call To `Login` Gateway Method
This commit is contained in:
parent
315be1d4ad
commit
e6238fcc9a
@ -63,10 +63,6 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
|
|
||||||
// start connection
|
// start connection
|
||||||
await HubConnection.StartAsync();
|
await HubConnection.StartAsync();
|
||||||
|
|
||||||
if (HubConnection != null && HubConnection.State == HubConnectionState.Connected)
|
|
||||||
// send login hub method
|
|
||||||
await HubConnection.SendAsync("LoginHub", _apiService.CurrentUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StopAsync()
|
public async Task StopAsync()
|
||||||
|
@ -68,12 +68,14 @@ namespace qtc_net_client_2.Forms
|
|||||||
|
|
||||||
while (_audioService.OutputDevice?.PlaybackState == NAudio.Wave.PlaybackState.Playing)
|
while (_audioService.OutputDevice?.PlaybackState == NAudio.Wave.PlaybackState.Playing)
|
||||||
{
|
{
|
||||||
|
if (!IsHandleCreated) return;
|
||||||
label.BeginInvoke(delegate () { label.Text = $"{rnd.Next(0, 300)} Q's Won"; });
|
label.BeginInvoke(delegate () { label.Text = $"{rnd.Next(0, 300)} Q's Won"; });
|
||||||
await Task.Delay(10);
|
await Task.Delay(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
var win = rnd.Next(0, 300);
|
var win = rnd.Next(0, 300);
|
||||||
|
|
||||||
|
if (!IsHandleCreated) return;
|
||||||
label.BeginInvoke(delegate ()
|
label.BeginInvoke(delegate ()
|
||||||
{
|
{
|
||||||
label.Text = $"{win} Q's Won";
|
label.Text = $"{win} Q's Won";
|
||||||
|
@ -15,6 +15,7 @@ namespace qtc_net_client_2
|
|||||||
private IGatewayService _gatewayService;
|
private IGatewayService _gatewayService;
|
||||||
private Config _config;
|
private Config _config;
|
||||||
private AudioService AudioService = new();
|
private AudioService AudioService = new();
|
||||||
|
private LoggingService LoggingService;
|
||||||
|
|
||||||
private List<Room> RoomList = [];
|
private List<Room> RoomList = [];
|
||||||
private List<UserInformationDto> OnlineUsers = [];
|
private List<UserInformationDto> OnlineUsers = [];
|
||||||
@ -22,17 +23,20 @@ namespace qtc_net_client_2
|
|||||||
private List<UserInformationDto> Contacts = [];
|
private List<UserInformationDto> Contacts = [];
|
||||||
|
|
||||||
private bool FirstMinimize = true;
|
private bool FirstMinimize = true;
|
||||||
public Main(IApiService apiService, IGatewayService gatewayService, Config config)
|
public Main(IApiService apiService, IGatewayService gatewayService, Config config, LoggingService loggingService)
|
||||||
{
|
{
|
||||||
_apiService = apiService;
|
_apiService = apiService;
|
||||||
_gatewayService = gatewayService;
|
_gatewayService = gatewayService;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
LoggingService = loggingService;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void frmMain_Load(object sender, EventArgs e)
|
private async void frmMain_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString("Main Form Loaded");
|
||||||
|
|
||||||
// start request notif blink task
|
// start request notif blink task
|
||||||
Thread blinkThread = new Thread(async () => await StartRequestNotifBlankLoop(lblRequestNotif));
|
Thread blinkThread = new Thread(async () => await StartRequestNotifBlankLoop(lblRequestNotif));
|
||||||
blinkThread.Start();
|
blinkThread.Start();
|
||||||
@ -73,6 +77,8 @@ namespace qtc_net_client_2
|
|||||||
|
|
||||||
Chat frmChat = new Chat(_gatewayService, _apiService);
|
Chat frmChat = new Chat(_gatewayService, _apiService);
|
||||||
frmChat.Show();
|
frmChat.Show();
|
||||||
|
|
||||||
|
LoggingService.LogString("User Has Joined Lobby Room");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +90,8 @@ namespace qtc_net_client_2
|
|||||||
|
|
||||||
Chat frmChat = new Chat(_gatewayService, _apiService);
|
Chat frmChat = new Chat(_gatewayService, _apiService);
|
||||||
frmChat.Show();
|
frmChat.Show();
|
||||||
|
|
||||||
|
LoggingService.LogString($"User Has Joined {room.Name}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,7 +126,7 @@ namespace qtc_net_client_2
|
|||||||
pbUserPfp.Image = Image.FromStream(ms);
|
pbUserPfp.Image = Image.FromStream(ms);
|
||||||
ms.Dispose();
|
ms.Dispose();
|
||||||
}
|
}
|
||||||
}
|
} else LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{pfpRes.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,8 +158,11 @@ namespace qtc_net_client_2
|
|||||||
var res = await _apiService.GetUserInformationAsync(user!.Id);
|
var res = await _apiService.GetUserInformationAsync(user!.Id);
|
||||||
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
|
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
|
||||||
|
|
||||||
|
if (pfpRes != null && !pfpRes.Success) LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{pfpRes.Message}");
|
||||||
|
|
||||||
if (res.Data != null && res.Success)
|
if (res.Data != null && res.Success)
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString($"Opening Profile For User '{res.Data.Username}'");
|
||||||
Profile frmProfile = new Profile(res.Data, pfpRes, _apiService, _gatewayService);
|
Profile frmProfile = new Profile(res.Data, pfpRes, _apiService, _gatewayService);
|
||||||
frmProfile.Show();
|
frmProfile.Show();
|
||||||
}
|
}
|
||||||
@ -185,8 +196,11 @@ namespace qtc_net_client_2
|
|||||||
var res = await _apiService.GetUserInformationAsync(user!.Id);
|
var res = await _apiService.GetUserInformationAsync(user!.Id);
|
||||||
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
|
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
|
||||||
|
|
||||||
|
if (pfpRes != null && !pfpRes.Success) LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{pfpRes.Message}");
|
||||||
|
|
||||||
if (res.Data != null && res.Success)
|
if (res.Data != null && res.Success)
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString($"Opening Profile For User '{res.Data.Username}'");
|
||||||
Profile frmProfile = new Profile(res.Data, pfpRes, _apiService, _gatewayService);
|
Profile frmProfile = new Profile(res.Data, pfpRes, _apiService, _gatewayService);
|
||||||
frmProfile.Show();
|
frmProfile.Show();
|
||||||
}
|
}
|
||||||
@ -306,8 +320,11 @@ namespace qtc_net_client_2
|
|||||||
var res = await _apiService.GetUserInformationAsync(user!.Id);
|
var res = await _apiService.GetUserInformationAsync(user!.Id);
|
||||||
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
|
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
|
||||||
|
|
||||||
|
if (pfpRes != null && !pfpRes.Success) LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{pfpRes.Message}");
|
||||||
|
|
||||||
if (res.Data != null && res.Success)
|
if (res.Data != null && res.Success)
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString($"Opening Profile For User '{res.Data.Username}'");
|
||||||
Profile frmProfile = new Profile(res.Data, pfpRes, _apiService, _gatewayService);
|
Profile frmProfile = new Profile(res.Data, pfpRes, _apiService, _gatewayService);
|
||||||
frmProfile.Show();
|
frmProfile.Show();
|
||||||
}
|
}
|
||||||
@ -349,6 +366,9 @@ namespace qtc_net_client_2
|
|||||||
// double check
|
// double check
|
||||||
if (_apiService.CurrentUser != null && _apiService.SessionToken != null)
|
if (_apiService.CurrentUser != null && _apiService.SessionToken != null)
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString($"Logged In As '{_apiService.CurrentUser.Username}'");
|
||||||
|
LoggingService.LogString("Starting SignalR Connection...");
|
||||||
|
|
||||||
// start gateway connection
|
// start gateway connection
|
||||||
await _gatewayService.StartAsync();
|
await _gatewayService.StartAsync();
|
||||||
|
|
||||||
@ -364,6 +384,8 @@ namespace qtc_net_client_2
|
|||||||
|
|
||||||
if (_gatewayService.HubConnection != null && _gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
|
if (_gatewayService.HubConnection != null && _gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString("Connected To SignalR Succesfully.");
|
||||||
|
|
||||||
// we are fully logged in, get current user profile pic and set up ui
|
// we are fully logged in, get current user profile pic and set up ui
|
||||||
llblSignIn.Visible = false;
|
llblSignIn.Visible = false;
|
||||||
lblWelcome.Text = $"Welcome, {_apiService.CurrentUser.Username}";
|
lblWelcome.Text = $"Welcome, {_apiService.CurrentUser.Username}";
|
||||||
@ -430,12 +452,16 @@ namespace qtc_net_client_2
|
|||||||
else llblClaimSpin.Visible = false;
|
else llblClaimSpin.Visible = false;
|
||||||
|
|
||||||
if (_config.StartMinimized) WindowState = FormWindowState.Minimized;
|
if (_config.StartMinimized) WindowState = FormWindowState.Minimized;
|
||||||
|
|
||||||
|
LoggingService.LogString("Client Ready");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshOnlineUsersList()
|
private async Task RefreshOnlineUsersList()
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString("Refreshing Online Users List...");
|
||||||
|
|
||||||
if (InvokeRequired)
|
if (InvokeRequired)
|
||||||
{
|
{
|
||||||
await Invoke(async delegate ()
|
await Invoke(async delegate ()
|
||||||
@ -469,6 +495,8 @@ namespace qtc_net_client_2
|
|||||||
|
|
||||||
private async Task RefreshUserDirectory()
|
private async Task RefreshUserDirectory()
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString("Refreshing All Users List...");
|
||||||
|
|
||||||
// get all users on server
|
// get all users on server
|
||||||
var userList = await _apiService.GetAllUsersAsync();
|
var userList = await _apiService.GetAllUsersAsync();
|
||||||
|
|
||||||
@ -497,6 +525,8 @@ namespace qtc_net_client_2
|
|||||||
|
|
||||||
private async Task RefreshRoomsList()
|
private async Task RefreshRoomsList()
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString("Refreshing Rooms List...");
|
||||||
|
|
||||||
if (InvokeRequired)
|
if (InvokeRequired)
|
||||||
{
|
{
|
||||||
await Invoke(async delegate ()
|
await Invoke(async delegate ()
|
||||||
@ -536,6 +566,8 @@ namespace qtc_net_client_2
|
|||||||
|
|
||||||
private async Task RefreshContactsList()
|
private async Task RefreshContactsList()
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString("Refreshing Contacts List...");
|
||||||
|
|
||||||
if (InvokeRequired)
|
if (InvokeRequired)
|
||||||
{
|
{
|
||||||
await Invoke(async delegate ()
|
await Invoke(async delegate ()
|
||||||
@ -682,7 +714,9 @@ namespace qtc_net_client_2
|
|||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (InvokeRequired && label.IsHandleCreated)
|
if (!IsHandleCreated) { LoggingService.LogString("Form Handle Wasn't Created"); return; }
|
||||||
|
|
||||||
|
if (InvokeRequired)
|
||||||
{
|
{
|
||||||
await Invoke(async delegate ()
|
await Invoke(async delegate ()
|
||||||
{
|
{
|
||||||
@ -692,13 +726,11 @@ namespace qtc_net_client_2
|
|||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (label.IsHandleCreated)
|
|
||||||
{
|
label.ForeColor = Color.Red;
|
||||||
label.ForeColor = Color.Red;
|
await Task.Delay(500);
|
||||||
await Task.Delay(500);
|
label.ForeColor = Color.Blue;
|
||||||
label.ForeColor = Color.Blue;
|
await Task.Delay(500);
|
||||||
await Task.Delay(500);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -712,7 +744,7 @@ namespace qtc_net_client_2
|
|||||||
ilProfilePics.Images.Add(userId, Image.FromStream(ms));
|
ilProfilePics.Images.Add(userId, Image.FromStream(ms));
|
||||||
ms.Dispose();
|
ms.Dispose();
|
||||||
}
|
}
|
||||||
}
|
} else if (result != null) LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{result.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshCurrencyCounter()
|
public void RefreshCurrencyCounter()
|
||||||
@ -732,11 +764,13 @@ namespace qtc_net_client_2
|
|||||||
|
|
||||||
private async void _gatewayService_OnServerDisconnect(object? sender, EventArgs e)
|
private async void _gatewayService_OnServerDisconnect(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString("Disconnected From SignalR");
|
||||||
|
|
||||||
if (DialogResult == DialogResult.OK) return;
|
if (DialogResult == DialogResult.OK) return;
|
||||||
|
|
||||||
var args = (ServerConnectionClosedEventArgs)e;
|
var args = (ServerConnectionClosedEventArgs)e;
|
||||||
string? error = string.Empty;
|
string? error = string.Empty;
|
||||||
if (args.Error != null) error = args.Error.Message;
|
if (args.Error != null) { error = args.Error.Message; LoggingService.LogString($"{args.Error.Message}\n{args.Error.StackTrace}"); }
|
||||||
|
|
||||||
// disconnect can sometimes be caused by an expired JWT token, attempt connection restart
|
// disconnect can sometimes be caused by an expired JWT token, attempt connection restart
|
||||||
await _gatewayService.StopAsync();
|
await _gatewayService.StopAsync();
|
||||||
@ -781,10 +815,14 @@ namespace qtc_net_client_2
|
|||||||
{
|
{
|
||||||
var args = (ServerConfigEventArgs)e;
|
var args = (ServerConfigEventArgs)e;
|
||||||
|
|
||||||
|
LoggingService.LogString($"Server Config Received");
|
||||||
|
LoggingService.LogModel(args.ServerConfig);
|
||||||
|
|
||||||
if (args.ServerConfig != null)
|
if (args.ServerConfig != null)
|
||||||
{
|
{
|
||||||
if (args.ServerConfig.IsDown)
|
if (args.ServerConfig.IsDown)
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString("Server Is Marked As Down");
|
||||||
MessageBox.Show($"Sorry, This Server Is Currently Down.\nMessage: {args.ServerConfig.IsDownMessage}\n\nPlease Try Again Later");
|
MessageBox.Show($"Sorry, This Server Is Currently Down.\nMessage: {args.ServerConfig.IsDownMessage}\n\nPlease Try Again Later");
|
||||||
|
|
||||||
if (_gatewayService.HubConnection != null && _gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
|
if (_gatewayService.HubConnection != null && _gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
|
||||||
@ -801,6 +839,8 @@ namespace qtc_net_client_2
|
|||||||
{
|
{
|
||||||
var args = (DirectMessageEventArgs)e;
|
var args = (DirectMessageEventArgs)e;
|
||||||
|
|
||||||
|
LoggingService.LogString($"Direct Message Received From '{args.User.Username}'");
|
||||||
|
|
||||||
DirectMessage? existingForm = (DirectMessage?)Application.OpenForms.Cast<Form>().FirstOrDefault(e => e.Name == "DirectMessage");
|
DirectMessage? existingForm = (DirectMessage?)Application.OpenForms.Cast<Form>().FirstOrDefault(e => e.Name == "DirectMessage");
|
||||||
if (existingForm != null && existingForm.User.Id == args.User.Id)
|
if (existingForm != null && existingForm.User.Id == args.User.Id)
|
||||||
{
|
{
|
||||||
|
@ -15,6 +15,9 @@ namespace qtc_net_client_2
|
|||||||
[STAThread]
|
[STAThread]
|
||||||
static async Task Main()
|
static async Task Main()
|
||||||
{
|
{
|
||||||
|
// first thing, create a new log
|
||||||
|
LoggingService loggingService = new();
|
||||||
|
|
||||||
Config clientConfig = new Config();
|
Config clientConfig = new Config();
|
||||||
|
|
||||||
if(System.Diagnostics.Debugger.IsAttached)
|
if(System.Diagnostics.Debugger.IsAttached)
|
||||||
@ -68,10 +71,11 @@ namespace qtc_net_client_2
|
|||||||
// To customize application configuration such as set high DPI settings or default font,
|
// To customize application configuration such as set high DPI settings or default font,
|
||||||
// see https://aka.ms/applicationconfiguration.
|
// see https://aka.ms/applicationconfiguration.
|
||||||
ApplicationConfiguration.Initialize();
|
ApplicationConfiguration.Initialize();
|
||||||
Application.Run(new Main(api, gateway, clientConfig));
|
Application.Run(new Main(api, gateway, clientConfig, loggingService));
|
||||||
|
|
||||||
// if application loop is exited, dispose everything
|
// if application loop is exited, dispose everything
|
||||||
await gateway.DisposeAsync();
|
await gateway.DisposeAsync();
|
||||||
|
loggingService.Dispose();
|
||||||
|
|
||||||
api = null!; // shut up compiler >:(
|
api = null!; // shut up compiler >:(
|
||||||
gateway = null!;
|
gateway = null!;
|
||||||
|
@ -81,7 +81,7 @@ namespace qtc_net_client_2.Properties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to 4.1.1.
|
/// Looks up a localized string similar to 4.2.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string AssemblyVersion {
|
internal static string AssemblyVersion {
|
||||||
get {
|
get {
|
||||||
|
@ -161,7 +161,7 @@
|
|||||||
<value>..\Icons\MessageIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Icons\MessageIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AssemblyVersion" xml:space="preserve">
|
<data name="AssemblyVersion" xml:space="preserve">
|
||||||
<value>4.1.1</value>
|
<value>4.2</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LoginBanner" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="LoginBanner" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\LoginBanner.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Resources\LoginBanner.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
52
qtc-net-client-2/Services/LoggingService.cs
Normal file
52
qtc-net-client-2/Services/LoggingService.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace qtc_net_client_2.Services
|
||||||
|
{
|
||||||
|
public class LoggingService : IDisposable
|
||||||
|
{
|
||||||
|
private DateTime LogDate { get; set; }
|
||||||
|
private string LogFilePath { get; set; }
|
||||||
|
private StreamWriter LogFile { get; set; }
|
||||||
|
public LoggingService()
|
||||||
|
{
|
||||||
|
LogDate = DateTime.Now;
|
||||||
|
LogFilePath = $"./Logs/QtCClientLog_{LogDate.ToString("ddMMyyy-hhmm")}.log";
|
||||||
|
|
||||||
|
// create log file
|
||||||
|
|
||||||
|
if (!Directory.Exists("./Logs")) Directory.CreateDirectory("./Logs");
|
||||||
|
LogFile = new StreamWriter(File.Create(LogFilePath));
|
||||||
|
|
||||||
|
Debug.WriteLine($"Log File Created At {LogFilePath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogString(string message)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"({DateTime.Now.ToLocalTime().ToString("hh:mm")}) {message}");
|
||||||
|
LogFile.WriteLine($"({DateTime.Now.ToLocalTime().ToString("hh:mm")}) {message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogModel<T>(T model)
|
||||||
|
{
|
||||||
|
// serialize the model as json
|
||||||
|
string modelSerialized = JsonSerializer.Serialize(model, options: new JsonSerializerOptions { WriteIndented = true });
|
||||||
|
|
||||||
|
// log it
|
||||||
|
Debug.WriteLine($"({DateTime.Now.ToLocalTime().ToString("hh:mm")}) {modelSerialized}");
|
||||||
|
LogFile.WriteLine($"({DateTime.Now.ToLocalTime().ToString("hh:mm")}) {modelSerialized}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
LogFile.WriteLine("--- END OF LOG ---");
|
||||||
|
LogFile.Close();
|
||||||
|
LogFile.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user