Add configurable batch concurrency and delay for TCPing, Real Delay, and UDP Delay tests

This commit is contained in:
MrArrowww 2026-05-26 18:14:26 +03:30 committed by GitHub
parent 0a357fd1a7
commit 52af5f982d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 350 additions and 92 deletions

View file

@ -159,6 +159,8 @@ public class SpeedTestItem
public int MixedConcurrencyCount { get; set; }
public string IPAPIUrl { get; set; }
public string UdpTestTarget { get; set; }
public int BatchTesting { get; set; }
public int DelayInterval { get; set; }
}
[Serializable]

View file

@ -4473,6 +4473,46 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Batch Testing 的本地化字符串。
/// </summary>
public static string TbSettingsBatchTesting {
get {
return ResourceManager.GetString("TbSettingsBatchTesting", resourceCulture);
}
}
/// <summary>
/// 查找类似 Batch Testing Tip 的本地化字符串。
/// </summary>
public static string TbSettingsBatchTestingTip {
get {
return ResourceManager.GetString("TbSettingsBatchTestingTip", resourceCulture);
}
}
/// <summary>
/// 查找类似 Delay Interval 的本地化字符串。
/// </summary>
public static string TbSettingsDelayInterval {
get {
return ResourceManager.GetString("TbSettingsDelayInterval", resourceCulture);
}
}
/// <summary>
/// 查找类似 Delay Interval Tip 的本地化字符串。
/// </summary>
public static string TbSettingsDelayIntervalTip {
get {
return ResourceManager.GetString("TbSettingsDelayIntervalTip", resourceCulture);
}
}
/// <summary>
/// 查找类似 Auth user 的本地化字符串。
/// </summary>

View file

@ -949,10 +949,10 @@
<value>اندازه فونت</value>
</data>
<data name="TbSettingsSpeedTestTimeout" xml:space="preserve">
<value>یمقدار تاخیر تست سرعت منفرد</value>
<value>مقدار تاخیر تست سرعت منفرد</value>
</data>
<data name="TbSettingsSpeedTestUrl" xml:space="preserve">
<value>/آدرس اینترنتی SpeedTest</value>
<value>آدرس اینترنتی SpeedTest</value>
</data>
<data name="menuMoveTo" xml:space="preserve">
<value>بالا و پایین حرکت کنید</value>
@ -1261,7 +1261,7 @@
<value>فیلتر هسته</value>
</data>
<data name="TipActiveServer" xml:space="preserve">
<value>فعال سازی</value>
<value>فعال</value>
</data>
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>منبع فایل های جغرافیایی (اختیاری)</value>
@ -1705,10 +1705,22 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<value>Only for fetching self-signed certificates. This may expose you to MITM risks.</value>
</data>
<data name="menuUdpTestServer" xml:space="preserve">
<value>Test Configurations UDP Delay</value>
<value>تست تاخیر کانفیگ ها از طریق UDP</value>
</data>
<data name="TbSettingsUdpTestUrl" xml:space="preserve">
<value>UDP Test Url</value>
<value>آدرس تست تاخیر UDP</value>
</data>
<data name="TbSettingsBatchTesting" xml:space="preserve">
<value>تعداد تست همزمان در هر دسته</value>
</data>
<data name="TbSettingsBatchTestingTip" xml:space="preserve">
<value>تعداد کانفیگ هایی که به صورت همزمان در هر دسته تست می شوند. مقدار 0 یعنی بدون محدودیت</value>
</data>
<data name="TbSettingsDelayInterval" xml:space="preserve">
<value>تأخیر بین دسته ها بر حسب ثانیه</value>
</data>
<data name="TbSettingsDelayIntervalTip" xml:space="preserve">
<value>مدت زمان انتظار قبل از شروع دسته بعدی. مقدار 0 یعنی بدون تأخیر</value>
</data>
<data name="TbSettingsSendThrough" xml:space="preserve">
<value>Local outbound address (SendThrough)</value>

View file

@ -1710,6 +1710,18 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbSettingsUdpTestUrl" xml:space="preserve">
<value>UDP Test Url</value>
</data>
<data name="TbSettingsBatchTesting" xml:space="preserve">
<value>Concurrent Tests Per Batch</value>
</data>
<data name="TbSettingsBatchTestingTip" xml:space="preserve">
<value>Number of configurations tested simultaneously in each batch. Set 0 for unlimited.</value>
</data>
<data name="TbSettingsDelayInterval" xml:space="preserve">
<value>Delay Between Batches (seconds)</value>
</data>
<data name="TbSettingsDelayIntervalTip" xml:space="preserve">
<value>Wait time before starting the next batch. Set 0 to disable delay.</value>
</data>
<data name="TbSettingsSendThrough" xml:space="preserve">
<value>Local outbound address (SendThrough)</value>
</data>

View file

@ -8,7 +8,6 @@ public class SpeedtestService(Config config, Func<SpeedTestResult, Task> updateF
private readonly Config? _config = config;
private readonly Func<SpeedTestResult, Task>? _updateFunc = updateFunc;
private static readonly ConcurrentBag<string> _lstExitLoop = new();
public void RunLoop(ESpeedActionType actionType, List<ProfileItem> selecteds)
{
Task.Run(async () =>
@ -44,7 +43,7 @@ public class SpeedtestService(Config config, Func<SpeedTestResult, Task> updateF
switch (actionType)
{
case ESpeedActionType.Tcping:
await RunTcpingAsync(lstSelected);
await RunTcpingAsync(lstSelected, exitLoopKey);
break;
case ESpeedActionType.Realping:
@ -133,17 +132,50 @@ public class SpeedtestService(Config config, Func<SpeedTestResult, Task> updateF
return lstSelected;
}
private async Task RunTcpingAsync(List<ServerTestItem> selecteds)
private async Task RunTcpingAsync(List<ServerTestItem> selecteds, string exitLoopKey)
{
int batchSize = _config.SpeedTestItem.BatchTesting;
int delay = _config.SpeedTestItem.DelayInterval;
if (batchSize <= 0)
{
batchSize = selecteds.Count;
}
for (int i = 0; i < selecteds.Count; i += batchSize)
{
if (ShouldStopTest(exitLoopKey))
{
return;
}
var batch = selecteds.Skip(i).Take(batchSize).ToList();
List<Task> tasks = [];
foreach (var it in selecteds)
foreach (var it in batch)
{
if (ShouldStopTest(exitLoopKey))
{
return;
}
tasks.Add(Task.Run(async () =>
{
try
{
if (ShouldStopTest(exitLoopKey))
{
return;
}
var responseTime = await GetTcpingTime(it.Address, it.Port);
if (ShouldStopTest(exitLoopKey))
{
return;
}
ProfileExManager.Instance.SetTestDelay(it.IndexId, responseTime);
await UpdateFunc(it.IndexId, responseTime.ToString());
}
@ -153,7 +185,14 @@ public class SpeedtestService(Config config, Func<SpeedTestResult, Task> updateF
}
}));
}
await Task.WhenAll(tasks);
if (delay > 0 && i + batchSize < selecteds.Count)
{
await Task.Delay(TimeSpan.FromSeconds(delay));
}
}
}
private async Task RunRealPingBatchAsync(List<ServerTestItem> lstSelected, string exitLoopKey, int pageSize = 0)
@ -210,8 +249,21 @@ public class SpeedtestService(Config config, Func<SpeedTestResult, Task> updateF
}
await Task.Delay(1000);
int batchSize = _config.SpeedTestItem.BatchTesting;
int delay = _config.SpeedTestItem.DelayInterval;
if (batchSize <= 0)
{
batchSize = selecteds.Count;
}
for (int i = 0; i < selecteds.Count; i += batchSize)
{
var batch = selecteds.Skip(i).Take(batchSize).ToList();
List<Task> tasks = new();
foreach (var it in selecteds)
foreach (var it in batch)
{
if (!it.AllowTest)
{
@ -229,7 +281,14 @@ public class SpeedtestService(Config config, Func<SpeedTestResult, Task> updateF
await DoRealPing(it);
}));
}
await Task.WhenAll(tasks);
if (delay > 0 && i + batchSize < selecteds.Count)
{
await Task.Delay(TimeSpan.FromSeconds(delay));
}
}
}
catch (Exception ex)
{
@ -291,8 +350,21 @@ public class SpeedtestService(Config config, Func<SpeedTestResult, Task> updateF
}
await Task.Delay(1000);
int batchSize = _config.SpeedTestItem.BatchTesting;
int delay = _config.SpeedTestItem.DelayInterval;
if (batchSize <= 0)
{
batchSize = selecteds.Count;
}
for (int i = 0; i < selecteds.Count; i += batchSize)
{
var batch = selecteds.Skip(i).Take(batchSize).ToList();
List<Task> tasks = new();
foreach (var it in selecteds)
foreach (var it in batch)
{
if (!it.AllowTest)
{
@ -309,7 +381,14 @@ public class SpeedtestService(Config config, Func<SpeedTestResult, Task> updateF
await DoUdpTest(it);
}));
}
await Task.WhenAll(tasks);
if (delay > 0 && i + batchSize < selecteds.Count)
{
await Task.Delay(TimeSpan.FromSeconds(delay));
}
}
}
catch (Exception ex)
{

View file

@ -62,6 +62,8 @@ public class OptionSettingViewModel : MyReactiveObject
[Reactive] public string SpeedPingTestUrl { get; set; }
[Reactive] public string UdpTestTarget { get; set; }
[Reactive] public int MixedConcurrencyCount { get; set; }
[Reactive] public string BatchTesting { get; set; }
[Reactive] public string DelayInterval { get; set; }
[Reactive] public bool EnableHWA { get; set; }
[Reactive] public string SubConvertUrl { get; set; }
[Reactive] public int MainGirdOrientation { get; set; }
@ -197,6 +199,8 @@ public class OptionSettingViewModel : MyReactiveObject
SpeedTestTimeout = _config.SpeedTestItem.SpeedTestTimeout;
SpeedTestUrl = _config.SpeedTestItem.SpeedTestUrl;
MixedConcurrencyCount = _config.SpeedTestItem.MixedConcurrencyCount;
BatchTesting = _config.SpeedTestItem.BatchTesting.ToString();
DelayInterval = _config.SpeedTestItem.DelayInterval.ToString();
SpeedPingTestUrl = _config.SpeedTestItem.SpeedPingTestUrl;
UdpTestTarget = _config.SpeedTestItem.UdpTestTarget;
EnableHWA = _config.GuiItem.EnableHWA;
@ -371,6 +375,10 @@ public class OptionSettingViewModel : MyReactiveObject
_config.UiItem.CurrentFontFamily = CurrentFontFamily;
_config.SpeedTestItem.SpeedTestTimeout = SpeedTestTimeout;
_config.SpeedTestItem.MixedConcurrencyCount = MixedConcurrencyCount;
int.TryParse(BatchTesting, out var batchTesting);
int.TryParse(DelayInterval, out var delayInterval);
_config.SpeedTestItem.BatchTesting = batchTesting;
_config.SpeedTestItem.DelayInterval = delayInterval;
_config.SpeedTestItem.SpeedTestUrl = SpeedTestUrl;
_config.SpeedTestItem.SpeedPingTestUrl = SpeedPingTestUrl;
_config.SpeedTestItem.UdpTestTarget = UdpTestTarget;

View file

@ -375,7 +375,7 @@
<Grid
Margin="{StaticResource Margin4}"
ColumnDefinitions="Auto,Auto,*"
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
<TextBlock
x:Name="tbAutoRun"
@ -616,63 +616,112 @@
Width="200"
Margin="{StaticResource Margin4}"
IsEditable="True" />
<TextBlock
Grid.Row="22"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsBatchTesting}" />
<TextBox
x:Name="txtBatchTesting"
Grid.Row="22"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
Text="{Binding BatchTesting}"
Watermark="0" />
<TextBlock
Grid.Row="22"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsBatchTestingTip}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="23"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsDelayInterval}" />
<TextBox
x:Name="txtDelayInterval"
Grid.Row="23"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
Text="{Binding DelayInterval}"
Watermark="0" />
<TextBlock
Grid.Row="23"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsDelayIntervalTip}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="24"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsIPAPIUrl}" />
<ComboBox
x:Name="cmbIPAPIUrl"
Grid.Row="22"
Grid.Row="24"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin4}"
IsEditable="True" />
<TextBlock
Grid.Row="23"
Grid.Row="25"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsSubConvert}" />
<ComboBox
x:Name="cmbSubConvertUrl"
Grid.Row="23"
Grid.Row="25"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin4}"
IsEditable="True" />
<TextBlock
Grid.Row="24"
Grid.Row="26"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsMainGirdOrientation}" />
<ComboBox
x:Name="cmbMainGirdOrientation"
Grid.Row="24"
Grid.Row="26"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}" />
<TextBlock
Grid.Row="25"
Grid.Row="27"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsGeoFilesSource}" />
<ComboBox
x:Name="cmbGetFilesSourceUrl"
Grid.Row="25"
Grid.Row="27"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin4}"
IsEditable="True" />
<TextBlock
Grid.Row="25"
Grid.Row="27"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
@ -680,20 +729,20 @@
TextWrapping="Wrap" />
<TextBlock
Grid.Row="26"
Grid.Row="28"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsSrsFilesSource}" />
<ComboBox
x:Name="cmbSrsFilesSourceUrl"
Grid.Row="26"
Grid.Row="28"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin4}"
IsEditable="True" />
<TextBlock
Grid.Row="26"
Grid.Row="28"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
@ -701,20 +750,20 @@
TextWrapping="Wrap" />
<TextBlock
Grid.Row="27"
Grid.Row="29"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsRoutingRulesSource}" />
<ComboBox
x:Name="cmbRoutingRulesSourceUrl"
Grid.Row="27"
Grid.Row="29"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin4}"
IsEditable="True" />
<TextBlock
Grid.Row="27"
Grid.Row="29"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"

View file

@ -101,6 +101,8 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
this.Bind(ViewModel, vm => vm.SpeedPingTestUrl, v => v.cmbSpeedPingTestUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.UdpTestTarget, v => v.cmbUdpTestTarget.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.MixedConcurrencyCount, v => v.cmbMixedConcurrencyCount.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.BatchTesting, v => v.txtBatchTesting.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DelayInterval, v => v.txtDelayInterval.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SubConvertUrl, v => v.cmbSubConvertUrl.Text).DisposeWith(disposables);
this.Bind<OptionSettingViewModel, OptionSettingWindow, int, int>(ViewModel,
vm => vm.MainGirdOrientation, view => view.cmbMainGirdOrientation.SelectedIndex).DisposeWith(disposables);

View file

@ -66,6 +66,8 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@ -595,6 +597,8 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@ -869,17 +873,65 @@
Margin="{StaticResource Margin8}"
IsEditable="True"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="22"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsBatchTesting}" />
<TextBox
x:Name="txtBatchTesting"
Grid.Row="22"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}"
materialDesign:HintAssist.Hint="0" />
<TextBlock
Grid.Row="22"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsBatchTestingTip}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="23"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsDelayInterval}" />
<TextBox
x:Name="txtDelayInterval"
Grid.Row="23"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}"
materialDesign:HintAssist.Hint="0" />
<TextBlock
Grid.Row="23"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsDelayIntervalTip}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="24"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsIPAPIUrl}" />
<ComboBox
x:Name="cmbIPAPIUrl"
Grid.Row="22"
Grid.Row="24"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin8}"
@ -887,7 +939,7 @@
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="23"
Grid.Row="25"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
@ -895,7 +947,7 @@
Text="{x:Static resx:ResUI.TbSettingsSubConvert}" />
<ComboBox
x:Name="cmbSubConvertUrl"
Grid.Row="23"
Grid.Row="25"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin8}"
@ -904,7 +956,7 @@
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="24"
Grid.Row="26"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
@ -912,14 +964,14 @@
Text="{x:Static resx:ResUI.TbSettingsMainGirdOrientation}" />
<ComboBox
x:Name="cmbMainGirdOrientation"
Grid.Row="24"
Grid.Row="26"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin8}"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="25"
Grid.Row="27"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
@ -927,14 +979,14 @@
Text="{x:Static resx:ResUI.TbSettingsGeoFilesSource}" />
<ComboBox
x:Name="cmbGetFilesSourceUrl"
Grid.Row="25"
Grid.Row="27"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin8}"
IsEditable="True"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="25"
Grid.Row="27"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
@ -943,7 +995,7 @@
TextWrapping="Wrap" />
<TextBlock
Grid.Row="26"
Grid.Row="28"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
@ -951,14 +1003,14 @@
Text="{x:Static resx:ResUI.TbSettingsSrsFilesSource}" />
<ComboBox
x:Name="cmbSrsFilesSourceUrl"
Grid.Row="26"
Grid.Row="28"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin8}"
IsEditable="True"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="26"
Grid.Row="28"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
@ -967,7 +1019,7 @@
TextWrapping="Wrap" />
<TextBlock
Grid.Row="27"
Grid.Row="29"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
@ -975,14 +1027,14 @@
Text="{x:Static resx:ResUI.TbSettingsRoutingRulesSource}" />
<ComboBox
x:Name="cmbRoutingRulesSourceUrl"
Grid.Row="27"
Grid.Row="29"
Grid.Column="1"
Width="300"
Margin="{StaticResource Margin8}"
IsEditable="True"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="27"
Grid.Row="29"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"

View file

@ -106,6 +106,8 @@ public partial class OptionSettingWindow
this.Bind(ViewModel, vm => vm.SpeedPingTestUrl, v => v.cmbSpeedPingTestUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.UdpTestTarget, v => v.cmbUdpTestTarget.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.MixedConcurrencyCount, v => v.cmbMixedConcurrencyCount.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.BatchTesting, v => v.txtBatchTesting.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DelayInterval, v => v.txtDelayInterval.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableHWA, v => v.togEnableHWA.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SubConvertUrl, v => v.cmbSubConvertUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.MainGirdOrientation, v => v.cmbMainGirdOrientation.SelectedIndex).DisposeWith(disposables);