Add an option to check for update without proxy (#10090)

Checking for updates always dialed through the local proxy, which fails
exactly when an update may be needed most - when no working server is
available. Like the subscription-update menu, updating without the proxy
is now possible: the Check Update window gets an "Update via proxy"
toggle (persisted, on by default so existing behavior is unchanged),
honored by the check-only, update and geo-file flows, and by the
scheduled update check.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
patterniha
2026-09-04 06:35:10 +03:30
committed by GitHub
parent 9451b69246
commit df32b4d6cc
13 changed files with 85 additions and 24 deletions
+1 -1
View File
@@ -136,7 +136,7 @@ public class TaskManager
var updateService = new UpdateService(_config, async (success, msg) => await Task.CompletedTask); var updateService = new UpdateService(_config, async (success, msg) => await Task.CompletedTask);
var msgs = await updateService.CheckHasUpdateOnlyAll(_config.CheckUpdateItem.CheckPreReleaseUpdate); var msgs = await updateService.CheckHasUpdateOnlyAll(_config.CheckUpdateItem.CheckPreReleaseUpdate, _config.CheckUpdateItem.UpdateViaProxy);
foreach (var msg in msgs) foreach (var msg in msgs)
{ {
await _updateFunc?.Invoke(false, msg); await _updateFunc?.Invoke(false, msg);
@@ -243,6 +243,7 @@ public class WebDavItem
public class CheckUpdateItem public class CheckUpdateItem
{ {
public bool CheckPreReleaseUpdate { get; set; } public bool CheckPreReleaseUpdate { get; set; }
public bool UpdateViaProxy { get; set; } = true;
public List<string>? SelectedCoreTypes { get; set; } public List<string>? SelectedCoreTypes { get; set; }
} }
+9
View File
@@ -4238,6 +4238,15 @@ namespace ServiceLib.Resx {
return ResourceManager.GetString("TbSettingsEnableCheckPreReleaseUpdate", resourceCulture); return ResourceManager.GetString("TbSettingsEnableCheckPreReleaseUpdate", resourceCulture);
} }
} }
/// <summary>
/// 查找类似 Update via proxy 的本地化字符串。
/// </summary>
public static string TbSettingsEnableUpdateViaProxy {
get {
return ResourceManager.GetString("TbSettingsEnableUpdateViaProxy", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Enable sorting Configurations by drag-n-drop (requires restart) 的本地化字符串。 /// 查找类似 Enable sorting Configurations by drag-n-drop (requires restart) 的本地化字符串。
+3
View File
@@ -693,6 +693,9 @@
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve"> <data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
<value>به روز رسانی های پیش از انتشار را بررسی شود</value> <value>به روز رسانی های پیش از انتشار را بررسی شود</value>
</data> </data>
<data name="TbSettingsEnableUpdateViaProxy" xml:space="preserve">
<value>به‌روزرسانی از طریق پروکسی</value>
</data>
<data name="TbSettingsException" xml:space="preserve"> <data name="TbSettingsException" xml:space="preserve">
<value>استثنا</value> <value>استثنا</value>
</data> </data>
+3
View File
@@ -693,6 +693,9 @@
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve"> <data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
<value>Check for pre-release</value> <value>Check for pre-release</value>
</data> </data>
<data name="TbSettingsEnableUpdateViaProxy" xml:space="preserve">
<value>Update via proxy</value>
</data>
<data name="TbSettingsException" xml:space="preserve"> <data name="TbSettingsException" xml:space="preserve">
<value>Exception</value> <value>Exception</value>
</data> </data>
@@ -693,6 +693,9 @@
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve"> <data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
<value>检查 Pre-Release</value> <value>检查 Pre-Release</value>
</data> </data>
<data name="TbSettingsEnableUpdateViaProxy" xml:space="preserve">
<value>通过代理更新</value>
</data>
<data name="TbSettingsException" xml:space="preserve"> <data name="TbSettingsException" xml:space="preserve">
<value>例外</value> <value>例外</value>
</data> </data>
@@ -693,6 +693,9 @@
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve"> <data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
<value>檢查 Pre-Release</value> <value>檢查 Pre-Release</value>
</data> </data>
<data name="TbSettingsEnableUpdateViaProxy" xml:space="preserve">
<value>透過代理更新</value>
</data>
<data name="TbSettingsException" xml:space="preserve"> <data name="TbSettingsException" xml:space="preserve">
<value>例外</value> <value>例外</value>
</data> </data>
+19 -19
View File
@@ -7,7 +7,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
private readonly int _timeout = 30; private readonly int _timeout = 30;
private static readonly string _tag = "UpdateService"; private static readonly string _tag = "UpdateService";
public async Task CheckUpdateGuiN(bool preRelease) public async Task CheckUpdateGuiN(bool preRelease, bool blProxy = true)
{ {
var url = string.Empty; var url = string.Empty;
var fileName = string.Empty; var fileName = string.Empty;
@@ -31,7 +31,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
}; };
await UpdateFunc(false, string.Format(ResUI.MsgStartUpdating, ECoreType.v2rayN)); await UpdateFunc(false, string.Format(ResUI.MsgStartUpdating, ECoreType.v2rayN));
var result = await CheckUpdateAsync(downloadHandle, ECoreType.v2rayN, preRelease); var result = await CheckUpdateAsync(downloadHandle, ECoreType.v2rayN, preRelease, blProxy);
if (result.Success) if (result.Success)
{ {
await UpdateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, ECoreType.v2rayN)); await UpdateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, ECoreType.v2rayN));
@@ -39,7 +39,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
url = result.Url!; url = result.Url!;
fileName = Utils.GetTempPath(Utils.GetGuid()); fileName = Utils.GetTempPath(Utils.GetGuid());
await downloadHandle.DownloadFileAsync(new() { FileUrl = url, FilePath = fileName }, true, TimeSpan.FromSeconds(_timeout)); await downloadHandle.DownloadFileAsync(new() { FileUrl = url, FilePath = fileName }, blProxy, TimeSpan.FromSeconds(_timeout));
} }
else else
{ {
@@ -47,7 +47,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
} }
} }
public async Task CheckUpdateCore(ECoreType type, bool preRelease) public async Task CheckUpdateCore(ECoreType type, bool preRelease, bool blProxy = true)
{ {
var url = string.Empty; var url = string.Empty;
var fileName = string.Empty; var fileName = string.Empty;
@@ -80,7 +80,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
}; };
await UpdateFunc(false, string.Format(ResUI.MsgStartUpdating, type)); await UpdateFunc(false, string.Format(ResUI.MsgStartUpdating, type));
var result = await CheckUpdateAsync(downloadHandle, type, preRelease); var result = await CheckUpdateAsync(downloadHandle, type, preRelease, blProxy);
if (result.Success) if (result.Success)
{ {
await UpdateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, type)); await UpdateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, type));
@@ -89,7 +89,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
url = result.Url!; url = result.Url!;
var ext = url.Contains(".tar.gz") ? ".tar.gz" : Path.GetExtension(url); var ext = url.Contains(".tar.gz") ? ".tar.gz" : Path.GetExtension(url);
fileName = Utils.GetTempPath(Utils.GetGuid() + ext); fileName = Utils.GetTempPath(Utils.GetGuid() + ext);
await downloadHandle.DownloadFileAsync(new() { FileUrl = url, FilePath = fileName }, true, TimeSpan.FromSeconds(_timeout)); await downloadHandle.DownloadFileAsync(new() { FileUrl = url, FilePath = fileName }, blProxy, TimeSpan.FromSeconds(_timeout));
} }
else else
{ {
@@ -100,7 +100,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
} }
} }
public async Task<UpdateResult> CheckHasUpdateOnly(ECoreType type, bool preRelease) public async Task<UpdateResult> CheckHasUpdateOnly(ECoreType type, bool preRelease, bool blProxy = true)
{ {
if (!CoreInfoManager.Instance.IsCheckUpdateSupported(type)) if (!CoreInfoManager.Instance.IsCheckUpdateSupported(type))
{ {
@@ -109,10 +109,10 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
var downloadHandle = new DownloadService(); var downloadHandle = new DownloadService();
var checkPreRelease = CoreInfoManager.Instance.GetCheckPreRelease(type, preRelease); var checkPreRelease = CoreInfoManager.Instance.GetCheckPreRelease(type, preRelease);
return await CheckUpdateAsync(downloadHandle, type, checkPreRelease); return await CheckUpdateAsync(downloadHandle, type, checkPreRelease, blProxy);
} }
public async Task<List<string>> CheckHasUpdateOnlyAll(bool preRelease) public async Task<List<string>> CheckHasUpdateOnlyAll(bool preRelease, bool blProxy = true)
{ {
var msgs = new List<string>(); var msgs = new List<string>();
foreach (var type in CoreInfoManager.Instance.GetCheckUpdateCoreTypes()) foreach (var type in CoreInfoManager.Instance.GetCheckUpdateCoreTypes())
@@ -122,7 +122,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
continue; continue;
} }
var result = await CheckHasUpdateOnly(type, preRelease); var result = await CheckHasUpdateOnly(type, preRelease, blProxy);
if (result.Success && result.Version != null) if (result.Success && result.Version != null)
{ {
var msg = string.Format(ResUI.MsgCheckUpdateHasNewVersion, type, result.Version); var msg = string.Format(ResUI.MsgCheckUpdateHasNewVersion, type, result.Version);
@@ -137,7 +137,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
return msgs; return msgs;
} }
public async Task UpdateGeoFileAll() public async Task UpdateGeoFileAll(bool blProxy = true)
{ {
var requests = new List<FileDownloadRequest>(); var requests = new List<FileDownloadRequest>();
requests.AddRange(GetGeoFilesRequest()); requests.AddRange(GetGeoFilesRequest());
@@ -145,17 +145,17 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
requests.AddRange(await GetSrsFileAllRequest()); requests.AddRange(await GetSrsFileAllRequest());
// NOTE: srs files are more small, so we reverse the order to ensure a good download experience for the user. // NOTE: srs files are more small, so we reverse the order to ensure a good download experience for the user.
requests.Reverse(); requests.Reverse();
await DownloadGeoFiles(requests); await DownloadGeoFiles(requests, blProxy);
await UpdateFunc(true, string.Format(ResUI.MsgDownloadGeoFileSuccessfully, "geo")); await UpdateFunc(true, string.Format(ResUI.MsgDownloadGeoFileSuccessfully, "geo"));
} }
#region CheckUpdate private #region CheckUpdate private
private async Task<UpdateResult> CheckUpdateAsync(DownloadService downloadHandle, ECoreType type, bool preRelease) private async Task<UpdateResult> CheckUpdateAsync(DownloadService downloadHandle, ECoreType type, bool preRelease, bool blProxy)
{ {
try try
{ {
var result = await GetRemoteVersion(downloadHandle, type, preRelease); var result = await GetRemoteVersion(downloadHandle, type, preRelease, blProxy);
if (!result.Success || result.Version is null) if (!result.Success || result.Version is null)
{ {
return result; return result;
@@ -170,14 +170,14 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
} }
} }
private async Task<UpdateResult> GetRemoteVersion(DownloadService downloadHandle, ECoreType type, bool preRelease) private async Task<UpdateResult> GetRemoteVersion(DownloadService downloadHandle, ECoreType type, bool preRelease, bool blProxy)
{ {
var coreInfo = CoreInfoManager.Instance.GetCoreInfo(type); var coreInfo = CoreInfoManager.Instance.GetCoreInfo(type);
var tagName = string.Empty; var tagName = string.Empty;
if (preRelease || coreInfo?.LockedMaxVersion != null) if (preRelease || coreInfo?.LockedMaxVersion != null)
{ {
var url = coreInfo?.ReleaseApiUrl; var url = coreInfo?.ReleaseApiUrl;
var result = await downloadHandle.TryDownloadString(url, true, Global.AppName); var result = await downloadHandle.TryDownloadString(url, blProxy, Global.AppName);
if (result.IsNullOrEmpty()) if (result.IsNullOrEmpty())
{ {
return new UpdateResult(false, ""); return new UpdateResult(false, "");
@@ -209,7 +209,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
else else
{ {
var url = Path.Combine(coreInfo.Url, "latest"); var url = Path.Combine(coreInfo.Url, "latest");
var lastUrl = await downloadHandle.UrlRedirectAsync(url, true); var lastUrl = await downloadHandle.UrlRedirectAsync(url, blProxy);
if (lastUrl == null) if (lastUrl == null)
{ {
return new UpdateResult(false, ""); return new UpdateResult(false, "");
@@ -531,7 +531,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
}; };
} }
private async Task DownloadGeoFiles(List<FileDownloadRequest> requests) private async Task DownloadGeoFiles(List<FileDownloadRequest> requests, bool blProxy)
{ {
var tmpFilePathDict = new Dictionary<string, string>(); var tmpFilePathDict = new Dictionary<string, string>();
var tmpFileRequests = new List<FileDownloadRequest>(); var tmpFileRequests = new List<FileDownloadRequest>();
@@ -586,7 +586,7 @@ public partial class UpdateService(Config config, Func<bool, string, Task> updat
_ = UpdateFunc(false, args.GetException().Message); _ = UpdateFunc(false, args.GetException().Message);
}; };
await downloadHandle.DownloadSmallFilesAsync(tmpFileRequests, true, TimeSpan.FromSeconds(_timeout)); await downloadHandle.DownloadSmallFilesAsync(tmpFileRequests, blProxy, TimeSpan.FromSeconds(_timeout));
} }
#endregion Geo private #endregion Geo private
@@ -13,6 +13,7 @@ public partial class CheckUpdateViewModel : MyReactiveObject
public ReactiveCommand<RxVoid, RxVoid> CheckUpdateCmd { get; } public ReactiveCommand<RxVoid, RxVoid> CheckUpdateCmd { get; }
public ReactiveCommand<RxVoid, RxVoid> CheckOnlyCmd { get; } public ReactiveCommand<RxVoid, RxVoid> CheckOnlyCmd { get; }
[Reactive] public partial bool EnableCheckPreReleaseUpdate { get; set; } [Reactive] public partial bool EnableCheckPreReleaseUpdate { get; set; }
[Reactive] public partial bool EnableUpdateViaProxy { get; set; }
public CheckUpdateViewModel() public CheckUpdateViewModel()
{ {
@@ -33,12 +34,18 @@ public partial class CheckUpdateViewModel : MyReactiveObject
}); });
EnableCheckPreReleaseUpdate = _config.CheckUpdateItem.CheckPreReleaseUpdate; EnableCheckPreReleaseUpdate = _config.CheckUpdateItem.CheckPreReleaseUpdate;
EnableUpdateViaProxy = _config.CheckUpdateItem.UpdateViaProxy;
this.WhenAnyValue( this.WhenAnyValue(
x => x.EnableCheckPreReleaseUpdate, x => x.EnableCheckPreReleaseUpdate,
y => y == true) y => y == true)
.Subscribe(c => _ = OnCheckPreReleaseUpdateChanged()); .Subscribe(c => _ = OnCheckPreReleaseUpdateChanged());
this.WhenAnyValue(
x => x.EnableUpdateViaProxy,
y => y == true)
.Subscribe(c => _ = OnUpdateViaProxyChanged());
RefreshCheckUpdateItems(); RefreshCheckUpdateItems();
} }
@@ -98,6 +105,16 @@ public partial class CheckUpdateViewModel : MyReactiveObject
await SaveSelectedCoreTypes(); await SaveSelectedCoreTypes();
} }
private async Task OnUpdateViaProxyChanged()
{
if (_config.CheckUpdateItem.UpdateViaProxy == EnableUpdateViaProxy)
{
return;
}
_config.CheckUpdateItem.UpdateViaProxy = EnableUpdateViaProxy;
await SaveSelectedCoreTypes();
}
private async Task SaveSelectedCoreTypes() private async Task SaveSelectedCoreTypes()
{ {
_config.CheckUpdateItem.SelectedCoreTypes = _config.CheckUpdateItem.SelectedCoreTypes =
@@ -145,7 +162,7 @@ public partial class CheckUpdateViewModel : MyReactiveObject
} }
var updateService = new UpdateService(_config, async (success, msg) => await Task.CompletedTask); var updateService = new UpdateService(_config, async (success, msg) => await Task.CompletedTask);
var result = await updateService.CheckHasUpdateOnly(item.CoreType.Value, EnableCheckPreReleaseUpdate); var result = await updateService.CheckHasUpdateOnly(item.CoreType.Value, EnableCheckPreReleaseUpdate, EnableUpdateViaProxy);
if (result.Success && result.Version != null) if (result.Success && result.Version != null)
{ {
await UpdateView(item.CoreType, string.Format(ResUI.MsgCheckUpdateHasNewVersion, item.CoreType, result.Version)); await UpdateView(item.CoreType, string.Format(ResUI.MsgCheckUpdateHasNewVersion, item.CoreType, result.Version));
@@ -230,7 +247,7 @@ public partial class CheckUpdateViewModel : MyReactiveObject
UpdatedPlusPlus(null, ""); UpdatedPlusPlus(null, "");
} }
} }
await new UpdateService(_config, _updateUI).UpdateGeoFileAll() await new UpdateService(_config, _updateUI).UpdateGeoFileAll(EnableUpdateViaProxy)
.ContinueWith(t => UpdatedPlusPlus(null, "")); .ContinueWith(t => UpdatedPlusPlus(null, ""));
} }
@@ -245,7 +262,7 @@ public partial class CheckUpdateViewModel : MyReactiveObject
UpdatedPlusPlus(_v2rayN, msg); UpdatedPlusPlus(_v2rayN, msg);
} }
} }
await new UpdateService(_config, _updateUI).CheckUpdateGuiN(preRelease) await new UpdateService(_config, _updateUI).CheckUpdateGuiN(preRelease, EnableUpdateViaProxy)
.ContinueWith(t => UpdatedPlusPlus(_v2rayN, "")); .ContinueWith(t => UpdatedPlusPlus(_v2rayN, ""));
} }
@@ -263,7 +280,7 @@ public partial class CheckUpdateViewModel : MyReactiveObject
if (model.CoreType.HasValue) if (model.CoreType.HasValue)
{ {
await new UpdateService(_config, _updateUI).CheckUpdateCore(model.CoreType.Value, preRelease) await new UpdateService(_config, _updateUI).CheckUpdateCore(model.CoreType.Value, preRelease, EnableUpdateViaProxy)
.ContinueWith(t => UpdatedPlusPlus(model.CoreType, "")); .ContinueWith(t => UpdatedPlusPlus(model.CoreType, ""));
} }
} }
@@ -25,6 +25,16 @@
HorizontalAlignment="Center" HorizontalAlignment="Center"
Orientation="Horizontal"> Orientation="Horizontal">
<TextBlock
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsEnableUpdateViaProxy}" />
<ToggleSwitch
x:Name="togEnableUpdateViaProxy"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
<TextBlock <TextBlock
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
@@ -11,6 +11,7 @@ public partial class CheckUpdateView : ReactiveUserControl<CheckUpdateViewModel>
this.OneWayBind(ViewModel, vm => vm.CheckUpdateModels, v => v.lstCheckUpdates.ItemsSource).DisposeWith(disposables); this.OneWayBind(ViewModel, vm => vm.CheckUpdateModels, v => v.lstCheckUpdates.ItemsSource).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableUpdateViaProxy, v => v.togEnableUpdateViaProxy.IsChecked).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckOnlyCmd, v => v.btnCheckOnly).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.CheckOnlyCmd, v => v.btnCheckOnly).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables);
}); });
+10
View File
@@ -22,6 +22,16 @@
DockPanel.Dock="Bottom" DockPanel.Dock="Bottom"
Orientation="Horizontal"> Orientation="Horizontal">
<TextBlock
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsEnableUpdateViaProxy}" />
<ToggleButton
x:Name="togEnableUpdateViaProxy"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
<TextBlock <TextBlock
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
VerticalAlignment="Center" VerticalAlignment="Center"
@@ -11,6 +11,7 @@ public partial class CheckUpdateView
this.OneWayBind(ViewModel, vm => vm.CheckUpdateModels, v => v.lstCheckUpdates.ItemsSource).DisposeWith(disposables); this.OneWayBind(ViewModel, vm => vm.CheckUpdateModels, v => v.lstCheckUpdates.ItemsSource).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableUpdateViaProxy, v => v.togEnableUpdateViaProxy.IsChecked).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckOnlyCmd, v => v.btnCheckOnly).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.CheckOnlyCmd, v => v.btnCheckOnly).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables);
}); });