mirror of
https://github.com/netchx/netch.git
synced 2026-05-11 23:45:06 +08:00
控制器日志写入线程安全,主控制器启动停止等改为异步执行,修复主控制器停止提前释放
This commit is contained in:
@@ -105,7 +105,7 @@ namespace Netch.Controllers
|
|||||||
/// <param name="argument">主程序启动参数</param>
|
/// <param name="argument">主程序启动参数</param>
|
||||||
/// <param name="priority">进程优先级</param>
|
/// <param name="priority">进程优先级</param>
|
||||||
/// <returns>是否成功启动</returns>
|
/// <returns>是否成功启动</returns>
|
||||||
protected bool StartInstanceAuto(string argument, ProcessPriorityClass priority = ProcessPriorityClass.Normal)
|
protected bool StartInstanceAuto(string argument, ProcessPriorityClass priority = ProcessPriorityClass.RealTime)
|
||||||
{
|
{
|
||||||
State = State.Starting;
|
State = State.Starting;
|
||||||
try
|
try
|
||||||
@@ -183,14 +183,14 @@ namespace Netch.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender">发送者</param>
|
/// <param name="sender">发送者</param>
|
||||||
/// <param name="e">数据</param>
|
/// <param name="e">数据</param>
|
||||||
protected async void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
protected void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
// 程序结束, 接收到 null
|
// 程序结束, 接收到 null
|
||||||
if (e.Data == null)
|
if (e.Data == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var info = Encoding.GetEncoding(InstanceOutputEncoding).GetBytes(e.Data + Global.EOF);
|
var info = Encoding.GetEncoding(InstanceOutputEncoding).GetBytes(e.Data + Global.EOF);
|
||||||
await Write(info);
|
Task.Run(() => Write(info));
|
||||||
var str = Encoding.UTF8.GetString(info);
|
var str = Encoding.UTF8.GetString(info);
|
||||||
// 检查启动
|
// 检查启动
|
||||||
if (State == State.Starting)
|
if (State == State.Starting)
|
||||||
@@ -220,19 +220,24 @@ namespace Netch.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly object _fileLocker = new object();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 写入日志文件流
|
/// 写入日志文件流
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="info"></param>
|
/// <param name="info"></param>
|
||||||
/// <returns>转码后的字符串</returns>
|
/// <returns>转码后的字符串</returns>
|
||||||
private async Task Write(byte[] info)
|
private void Write(byte[] info)
|
||||||
{
|
{
|
||||||
if (info == null)
|
if (info == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _logFileStream.WriteAsync(info, 0, info.Length);
|
lock (_fileLocker)
|
||||||
|
{
|
||||||
|
_logFileStream.Write(info, 0, info.Length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ namespace Netch.Controllers
|
|||||||
/// <param name="server">服务器</param>
|
/// <param name="server">服务器</param>
|
||||||
/// <param name="mode">模式</param>
|
/// <param name="mode">模式</param>
|
||||||
/// <returns>是否启动成功</returns>
|
/// <returns>是否启动成功</returns>
|
||||||
public bool Start(Server server, Mode mode)
|
public async Task<bool> Start(Server server, Mode mode)
|
||||||
{
|
{
|
||||||
Logging.Info($"启动主控制器: {server.Type} [{mode.Type}]{mode.Remark}");
|
Logging.Info($"启动主控制器: {server.Type} [{mode.Type}]{mode.Remark}");
|
||||||
|
|
||||||
@@ -88,6 +88,7 @@ namespace Netch.Controllers
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
FlushDNSResolverCache();
|
FlushDNSResolverCache();
|
||||||
|
_ = Task.Run(Firewall.AddNetchFwRules);
|
||||||
|
|
||||||
bool result;
|
bool result;
|
||||||
if (server.Type == "Socks5")
|
if (server.Type == "Socks5")
|
||||||
@@ -111,17 +112,17 @@ namespace Netch.Controllers
|
|||||||
var isPortNotAvailable = false;
|
var isPortNotAvailable = false;
|
||||||
if (_savedServer.Type != "Socks5")
|
if (_savedServer.Type != "Socks5")
|
||||||
{
|
{
|
||||||
isPortNotAvailable = PortCheckAndShowMessageBox(_socks5Port, "Socks5");
|
isPortNotAvailable |= PortCheckAndShowMessageBox(_socks5Port, "Socks5");
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (_savedMode.Type)
|
switch (_savedMode.Type)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
isPortNotAvailable = isPortNotAvailable || PortCheckAndShowMessageBox(_redirectorTCPPort, "Redirector TCP");
|
isPortNotAvailable |= PortCheckAndShowMessageBox(_redirectorTCPPort, "Redirector TCP");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
case 5:
|
case 5:
|
||||||
isPortNotAvailable = isPortNotAvailable || PortCheckAndShowMessageBox(_httpPort, "HTTP");
|
isPortNotAvailable |= PortCheckAndShowMessageBox(_httpPort, "HTTP");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +133,7 @@ namespace Netch.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
Global.MainForm.StatusText(i18N.Translate("Starting ", pEncryptedProxyController.Name));
|
Global.MainForm.StatusText(i18N.Translate("Starting ", pEncryptedProxyController.Name));
|
||||||
result = pEncryptedProxyController.Start(server, mode);
|
result = await Task.Run(() => pEncryptedProxyController.Start(server, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
@@ -161,7 +162,7 @@ namespace Netch.Controllers
|
|||||||
if (pModeController != null)
|
if (pModeController != null)
|
||||||
{
|
{
|
||||||
Global.MainForm.StatusText(i18N.Translate("Starting ", pModeController.Name));
|
Global.MainForm.StatusText(i18N.Translate("Starting ", pModeController.Name));
|
||||||
result = pModeController.Start(server, mode);
|
result = await Task.Run(() => pModeController.Start(server, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
@@ -179,13 +180,12 @@ namespace Netch.Controllers
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (mode.Type)
|
switch (mode.Type)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
Task.Run(() =>
|
_ = Task.Run(() =>
|
||||||
{
|
{
|
||||||
Global.MainForm.NatTypeStatusText(i18N.Translate("Starting NatTester"));
|
Global.MainForm.NatTypeStatusText(i18N.Translate("Starting NatTester"));
|
||||||
// Thread.Sleep(1000);
|
// Thread.Sleep(1000);
|
||||||
@@ -202,7 +202,7 @@ namespace Netch.Controllers
|
|||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
Logging.Error("主控制器启动失败");
|
Logging.Error("主控制器启动失败");
|
||||||
Stop();
|
await Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -211,15 +211,16 @@ namespace Netch.Controllers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 停止
|
/// 停止
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async void Stop()
|
public async Task Stop()
|
||||||
{
|
{
|
||||||
await Task.WhenAll(new[]
|
var tasks = new Task[]
|
||||||
{
|
{
|
||||||
Task.Run(() => pEncryptedProxyController?.Stop()),
|
Task.Run(() => pEncryptedProxyController?.Stop()),
|
||||||
Task.Run(() => UsingPorts.Clear()),
|
Task.Run(() => UsingPorts.Clear()),
|
||||||
Task.Run(() => pModeController?.Stop()),
|
Task.Run(() => pModeController?.Stop()),
|
||||||
Task.Run(() => pNTTController.Stop())
|
Task.Run(() => pNTTController.Stop())
|
||||||
});
|
};
|
||||||
|
await Task.WhenAll(tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void KillProcessByName(string name)
|
public static void KillProcessByName(string name)
|
||||||
|
|||||||
@@ -175,18 +175,9 @@ namespace Netch.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!File.Exists(SystemDriver)) return true;
|
if (!File.Exists(SystemDriver)) return true;
|
||||||
|
NFAPI.nf_unRegisterDriver("netfilter2");
|
||||||
try
|
|
||||||
{
|
|
||||||
NFAPI.nf_unRegisterDriver("netfilter2");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Logging.Error(e.ToString());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
File.Delete(SystemDriver);
|
File.Delete(SystemDriver);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,26 +40,22 @@ namespace Netch.Forms
|
|||||||
|
|
||||||
State = State.Starting;
|
State = State.Starting;
|
||||||
|
|
||||||
await Task.Run(Firewall.AddNetchFwRules);
|
|
||||||
|
|
||||||
var server = ServerComboBox.SelectedItem as Models.Server;
|
var server = ServerComboBox.SelectedItem as Models.Server;
|
||||||
var mode = ModeComboBox.SelectedItem as Models.Mode;
|
var mode = ModeComboBox.SelectedItem as Models.Mode;
|
||||||
var result = false;
|
var result = false;
|
||||||
|
|
||||||
await Task.Run(() =>
|
try
|
||||||
{
|
{
|
||||||
try
|
// TODO 完善控制器异常处理
|
||||||
{
|
result = await _mainController.Start(server, mode);
|
||||||
// TODO 完善控制器异常处理
|
}
|
||||||
result = _mainController.Start(server, mode);
|
catch (Exception e)
|
||||||
}
|
{
|
||||||
catch (Exception e)
|
if (e is DllNotFoundException || e is FileNotFoundException)
|
||||||
{
|
MessageBoxX.Show(e.Message + "\n\n" + i18N.Translate("Missing File or runtime components"), owner: this);
|
||||||
if (e is DllNotFoundException || e is FileNotFoundException)
|
Netch.Application_OnException(null, new ThreadExceptionEventArgs(e));
|
||||||
MessageBoxX.Show(e.Message + "\n\n" + i18N.Translate("Missing File or runtime components"), owner: this);
|
}
|
||||||
Netch.Application_OnException(null, new ThreadExceptionEventArgs(e));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
@@ -106,7 +102,7 @@ namespace Netch.Forms
|
|||||||
{
|
{
|
||||||
// 停止
|
// 停止
|
||||||
State = State.Stopping;
|
State = State.Stopping;
|
||||||
_mainController.Stop();
|
await _mainController.Stop();
|
||||||
State = State.Stopped;
|
State = State.Stopped;
|
||||||
_ = Task.Run(TestServer);
|
_ = Task.Run(TestServer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ namespace Netch.Forms
|
|||||||
Remark = "ProxyUpdate",
|
Remark = "ProxyUpdate",
|
||||||
Type = 5
|
Type = 5
|
||||||
};
|
};
|
||||||
_mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode);
|
await _mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
var serverLock = new object();
|
var serverLock = new object();
|
||||||
@@ -157,16 +157,14 @@ namespace Netch.Forms
|
|||||||
lock (serverLock)
|
lock (serverLock)
|
||||||
{
|
{
|
||||||
Global.Settings.Server = Global.Settings.Server.Where(server => server.Group != item.Remark).ToList();
|
Global.Settings.Server = Global.Settings.Server.Where(server => server.Group != item.Remark).ToList();
|
||||||
}
|
var result = ShareLink.Parse(str);
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
foreach (var x in result) x.Group = item.Remark;
|
||||||
|
|
||||||
var result = ShareLink.Parse(str);
|
Global.Settings.Server.AddRange(result);
|
||||||
|
NotifyTip(i18N.TranslateFormat("Update {1} server(s) from {0}", item.Remark, result.Count));
|
||||||
if (result != null)
|
}
|
||||||
{
|
|
||||||
foreach (var x in result) x.Group = item.Remark;
|
|
||||||
|
|
||||||
Global.Settings.Server.AddRange(result);
|
|
||||||
NotifyTip(i18N.TranslateFormat("Update {1} server(s) from {0}", item.Remark, result.Count));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (WebException e)
|
catch (WebException e)
|
||||||
@@ -186,7 +184,7 @@ namespace Netch.Forms
|
|||||||
|
|
||||||
if (Global.Settings.UseProxyToUpdateSubscription)
|
if (Global.Settings.UseProxyToUpdateSubscription)
|
||||||
{
|
{
|
||||||
_mainController.Stop();
|
await _mainController.Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,13 +197,10 @@ namespace Netch.Forms
|
|||||||
Utils.Utils.Open(".\\");
|
Utils.Utils.Open(".\\");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CleanDNSCacheToolStripMenuItem_Click(object sender, EventArgs e)
|
private async void CleanDNSCacheToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
await Task.Run(() => DNS.Cache.Clear());
|
||||||
{
|
StatusText(i18N.Translate("DNS cache cleanup succeeded"));
|
||||||
DNS.Cache.Clear();
|
|
||||||
NotifyTip(i18N.Translate("DNS cache cleanup succeeded"));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReloadModesToolStripMenuItem_Click(object sender, EventArgs e)
|
private void ReloadModesToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
@@ -246,95 +241,83 @@ namespace Netch.Forms
|
|||||||
|
|
||||||
DisableItems(false);
|
DisableItems(false);
|
||||||
|
|
||||||
await Task.Run(async () =>
|
if (useProxy)
|
||||||
|
{
|
||||||
|
var mode = new Models.Mode
|
||||||
|
{
|
||||||
|
Remark = "ProxyUpdate",
|
||||||
|
Type = 5
|
||||||
|
};
|
||||||
|
State = State.Starting;
|
||||||
|
await _mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
NotifyTip(i18N.Translate("Updating in the background"));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var req = WebUtil.CreateRequest(Global.Settings.ACL);
|
||||||
|
if (useProxy)
|
||||||
|
req.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}");
|
||||||
|
|
||||||
|
await WebUtil.DownloadFileAsync(req, Path.Combine(Global.NetchDir, "bin\\default.acl"));
|
||||||
|
NotifyTip(i18N.Translate("ACL updated successfully"));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
NotifyTip(i18N.Translate("ACL update failed") + "\n" + e.Message, info: false);
|
||||||
|
Logging.Error("更新 ACL 失败!" + e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
{
|
{
|
||||||
if (useProxy)
|
if (useProxy)
|
||||||
{
|
{
|
||||||
var mode = new Models.Mode
|
await _mainController.Stop();
|
||||||
{
|
State = State.Stopped;
|
||||||
Remark = "ProxyUpdate",
|
|
||||||
Type = 5
|
|
||||||
};
|
|
||||||
State = State.Starting;
|
|
||||||
_mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NotifyTip(i18N.Translate("Updating in the background"));
|
DisableItems(true);
|
||||||
try
|
}
|
||||||
{
|
|
||||||
var req = WebUtil.CreateRequest(Global.Settings.ACL);
|
|
||||||
if (useProxy)
|
|
||||||
req.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}");
|
|
||||||
|
|
||||||
await WebUtil.DownloadFileAsync(req, Path.Combine(Global.NetchDir, "bin\\default.acl"));
|
|
||||||
NotifyTip(i18N.Translate("ACL updated successfully"));
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
NotifyTip(i18N.Translate("ACL update failed") + "\n" + e.Message, info: false);
|
|
||||||
Logging.Error("更新 ACL 失败!" + e);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (useProxy)
|
|
||||||
{
|
|
||||||
_mainController.Stop();
|
|
||||||
State = State.Stopped;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisableItems(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void UninstallServiceToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
private void UninstallServiceToolStripMenuItem_Click(object sender, EventArgs e)
|
|
||||||
{
|
{
|
||||||
Enabled = false;
|
Enabled = false;
|
||||||
StatusText(i18N.Translate("Uninstalling NF Service"));
|
StatusText(i18N.Translate("Uninstalling NF Service"));
|
||||||
|
|
||||||
Task.Run(() =>
|
var result = false;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
try
|
await Task.Run(() => result = NFController.UninstallDriver());
|
||||||
|
if (result)
|
||||||
{
|
{
|
||||||
if (NFController.UninstallDriver())
|
StatusText(i18N.Translate("Service has been uninstalled"));
|
||||||
{
|
|
||||||
StatusText(i18N.Translate("Service has been uninstalled"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
}
|
||||||
{
|
finally
|
||||||
MessageBoxX.Show(e.ToString(), LogLevel.ERROR);
|
{
|
||||||
Console.WriteLine(e);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reinstallTapDriverToolStripMenuItem_Click(object sender, EventArgs e)
|
private async void reinstallTapDriverToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
StatusText(i18N.Translate("Reinstalling TUN/TAP driver"));
|
||||||
|
Enabled = false;
|
||||||
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
StatusText(i18N.Translate("Reinstalling TUN/TAP driver"));
|
|
||||||
Enabled = false;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Configuration.deltapall();
|
Configuration.deltapall();
|
||||||
Configuration.addtap();
|
Configuration.addtap();
|
||||||
NotifyTip(i18N.Translate("Reinstall TUN/TAP driver successfully"));
|
StatusText(i18N.Translate("Reinstall TUN/TAP driver successfully"));
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
NotifyTip(i18N.Translate("Reinstall TUN/TAP driver failed"), info: false);
|
NotifyTip(i18N.Translate("Reinstall TUN/TAP driver failed"), info: false);
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
State = State.Waiting;
|
|
||||||
Enabled = true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
State = State.Waiting;
|
||||||
|
Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ using Netch.Utils;
|
|||||||
|
|
||||||
namespace Netch.Forms
|
namespace Netch.Forms
|
||||||
{
|
{
|
||||||
public partial class Dummy { }
|
public partial class Dummy
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
partial class MainForm
|
partial class MainForm
|
||||||
{
|
{
|
||||||
/// init at <see cref="MainForm_Load"/>
|
/// init at <see cref="MainForm_Load"/>
|
||||||
@@ -136,7 +139,7 @@ namespace Netch.Forms
|
|||||||
|
|
||||||
private List<Button> ProfileButtons = new List<Button>();
|
private List<Button> ProfileButtons = new List<Button>();
|
||||||
|
|
||||||
private void ProfileButton_Click(object sender, EventArgs e)
|
private async void ProfileButton_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var index = ProfileButtons.IndexOf((Button) sender);
|
var index = ProfileButtons.IndexOf((Button) sender);
|
||||||
|
|
||||||
@@ -159,6 +162,7 @@ namespace Netch.Forms
|
|||||||
SaveProfile(index);
|
SaveProfile(index);
|
||||||
ProfileButtons[index].Text = ProfileNameText.Text;
|
ProfileButtons[index].Text = ProfileNameText.Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,26 +189,20 @@ namespace Netch.Forms
|
|||||||
ControlFun();
|
ControlFun();
|
||||||
if (State == State.Stopping || State == State.Stopped)
|
if (State == State.Stopping || State == State.Stopped)
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
while (State != State.Stopped)
|
||||||
{
|
{
|
||||||
while (State != State.Stopped)
|
await Task.Delay(250);
|
||||||
{
|
}
|
||||||
Thread.Sleep(250);
|
|
||||||
}
|
|
||||||
|
|
||||||
ControlFun();
|
ControlFun();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ee)
|
catch (Exception ee)
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
Logging.Info(ee.ToString());
|
||||||
{
|
ProfileButtons[index].Text = i18N.Translate("Error");
|
||||||
Logging.Info(ee.ToString());
|
await Task.Delay(1200);
|
||||||
ProfileButtons[index].Text = i18N.Translate("Error");
|
ProfileButtons[index].Text = i18N.Translate("None");
|
||||||
Thread.Sleep(1200);
|
|
||||||
ProfileButtons[index].Text = i18N.Translate("None");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace Netch.Forms
|
|||||||
{
|
{
|
||||||
if (InvokeRequired)
|
if (InvokeRequired)
|
||||||
{
|
{
|
||||||
|
// TODO:使所有 State 赋值不在线程中执行然后移除此代码块
|
||||||
BeginInvoke(new Action(() => { State = value; }));
|
BeginInvoke(new Action(() => { State = value; }));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -33,9 +34,9 @@ namespace Netch.Forms
|
|||||||
ServerComboBox.Enabled =
|
ServerComboBox.Enabled =
|
||||||
ModeComboBox.Enabled =
|
ModeComboBox.Enabled =
|
||||||
EditModePictureBox.Enabled =
|
EditModePictureBox.Enabled =
|
||||||
EditServerPictureBox.Enabled =
|
EditServerPictureBox.Enabled =
|
||||||
DeleteModePictureBox.Enabled =
|
DeleteModePictureBox.Enabled =
|
||||||
DeleteServerPictureBox.Enabled = enabled;
|
DeleteServerPictureBox.Enabled = enabled;
|
||||||
|
|
||||||
// 启动需要禁用的控件
|
// 启动需要禁用的控件
|
||||||
UninstallServiceToolStripMenuItem.Enabled =
|
UninstallServiceToolStripMenuItem.Enabled =
|
||||||
|
|||||||
@@ -250,18 +250,15 @@ namespace Netch.Forms
|
|||||||
ControlFun();
|
ControlFun();
|
||||||
}
|
}
|
||||||
|
|
||||||
Task.Run(() =>
|
for (var i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < 16; i++)
|
if (State == State.Waiting || State == State.Stopped)
|
||||||
{
|
break;
|
||||||
if (State == State.Waiting || State == State.Stopped)
|
Thread.Sleep(250);
|
||||||
break;
|
}
|
||||||
Thread.Sleep(250);
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveConfigs();
|
SaveConfigs();
|
||||||
State = State.Terminating;
|
State = State.Terminating;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region MISC
|
#region MISC
|
||||||
@@ -467,6 +464,7 @@ namespace Netch.Forms
|
|||||||
|
|
||||||
private void NotifyTip(string text, int timeout = 0, bool info = true)
|
private void NotifyTip(string text, int timeout = 0, bool info = true)
|
||||||
{
|
{
|
||||||
|
// 会阻塞线程 timeout 秒
|
||||||
NotifyIcon.ShowBalloonTip(timeout,
|
NotifyIcon.ShowBalloonTip(timeout,
|
||||||
UpdateChecker.Name,
|
UpdateChecker.Name,
|
||||||
text,
|
text,
|
||||||
|
|||||||
@@ -35,9 +35,14 @@ namespace Netch.Utils
|
|||||||
Write(text, LogLevel.ERROR);
|
Write(text, LogLevel.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly object FileLock = new object();
|
||||||
|
|
||||||
private static void Write(string text, LogLevel logLevel)
|
private static void Write(string text, LogLevel logLevel)
|
||||||
{
|
{
|
||||||
File.AppendAllText(LogFile, $@"[{DateTime.Now}][{logLevel.ToString()}] {text}{Global.EOF}");
|
lock (FileLock)
|
||||||
|
{
|
||||||
|
File.AppendAllText(LogFile, $@"[{DateTime.Now}][{logLevel.ToString()}] {text}{Global.EOF}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user