Skip to content

Commit 67aa746

Browse files
committed
Refactor ListView for better performance and add cancellation handling.
Replaced default ListView with a DoubleBufferedListView to improve UI performance during updates. Introduced cancellation handling for long-running tasks, ensuring resources are properly disposed and user actions are responsive. Adjusted LmStudioClient parameters for clarity and consistency.
1 parent 9fd8ead commit 67aa746

File tree

4 files changed

+78
-29
lines changed

4 files changed

+78
-29
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Nikse.SubtitleEdit.PluginLogic.Controls;
2+
3+
public class DoubleBufferedListView : ListView
4+
{
5+
public DoubleBufferedListView()
6+
{
7+
DoubleBuffered = true;
8+
}
9+
}

source/Commas/Main.Designer.cs

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

source/Commas/Main.cs

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,85 @@ namespace Commas;
77
public partial class Main : Form
88
{
99
private readonly Subtitle _subtitle;
10+
private volatile bool _isProcessing;
1011

1112
public Main(Subtitle subtitle)
1213
{
1314
_subtitle = subtitle;
1415
InitializeComponent();
1516

1617
buttonOkay.DialogResult = DialogResult.OK;
18+
19+
Closing += (sender, args) => { _ = CancelAndDisposeResources(); };
20+
}
21+
22+
private bool CancelAndDisposeResources()
23+
{
24+
if (_isProcessing)
25+
{
26+
_cancellationTokenSource.Cancel();
27+
_cancellationTokenSource.Dispose();
28+
_isProcessing = false;
29+
return true;
30+
}
31+
32+
return false;
1733
}
1834

1935
private CancellationTokenSource _cancellationTokenSource;
2036

2137
private async void buttonFixComma_Click(object sender, EventArgs e)
2238
{
39+
if (CancelAndDisposeResources())
40+
{
41+
return;
42+
}
2343

2444
using var lmStudioClient = new LmStudioClient(textBoxEndPoint.Text, textBoxPrompt.Text);
2545

2646
// listView1.BeginUpdate();
2747
_cancellationTokenSource = new CancellationTokenSource();
2848

29-
IProgress<ListViewItem> progress = new Progress<ListViewItem>(listViewItem =>
49+
var previousPercentage = 0;
50+
IProgress<(ListViewItem, int)> progress = new Progress<(ListViewItem listViewItem, int index)>(item =>
3051
{
31-
listView1.Items.Add(listViewItem);
32-
listView1.Refresh();
52+
listView1.Items.Add(item.listViewItem);
53+
54+
var percentage = (item.index * 100 / _subtitle.Paragraphs.Count);
55+
// refresh every 5%
56+
if (percentage != previousPercentage && percentage % 5 == 0)
57+
{
58+
listView1.Refresh();
59+
previousPercentage = percentage;
60+
}
3361
});
34-
await Task.Run(async () =>
62+
63+
try
3564
{
36-
foreach (var paragraph in _subtitle.Paragraphs)
65+
await Task.Run(async () =>
3766
{
38-
var output = await lmStudioClient.SendAsync(paragraph.Text).ConfigureAwait(false);
39-
40-
if (!output.Equals(paragraph.Text, StringComparison.Ordinal))
67+
_isProcessing = true;
68+
for (var index = 0; index < _subtitle.Paragraphs.Count; index++)
4169
{
42-
progress.Report(new ListViewItem(paragraph.Text)
70+
if (_cancellationTokenSource.IsCancellationRequested)
71+
{
72+
_cancellationTokenSource.Token.ThrowIfCancellationRequested();
73+
}
74+
75+
var paragraph = _subtitle.Paragraphs[index];
76+
var output = await lmStudioClient.SendAsync(paragraph.Text).ConfigureAwait(false);
77+
78+
if (!output.Equals(paragraph.Text, StringComparison.Ordinal))
4379
{
44-
SubItems = { output, }
45-
});
80+
progress.Report((new ListViewItem(new[] { paragraph.Text, output }), index));
81+
}
4682
}
47-
}
48-
}, _cancellationTokenSource.Token);
83+
}, _cancellationTokenSource.Token).ConfigureAwait(false);
84+
}
85+
catch (Exception exception)
86+
{
87+
Console.WriteLine(exception);
88+
}
4989
// listView1.EndUpdate();
5090
}
5191
}
Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,23 @@ public LmStudioClient(string url, string prompt)
2222
public async Task<string> SendAsync(string text)
2323
{
2424
/*
25-
* curl http://0.0.0.0:1234/v1/chat/completions \
26-
-H "Content-Type: application/json" \
27-
-d '{
28-
"model": "deepseek-r1-distill-qwen-7b",
29-
"messages": [
30-
{ "role": "system", "content": "Always answer in rhymes." },
31-
{ "role": "user", "content": "Introduce yourself." }
32-
],
33-
"temperature": 0.7,
34-
"max_tokens": -1,
35-
"stream": true
36-
}'
37-
25+
curl http://0.0.0.0:1234/v1/chat/completions \
26+
-H "Content-Type: application/json" \
27+
-d '{
28+
"model": "deepseek-r1-distill-qwen-7b",
29+
"messages": [
30+
{ "role": "system", "content": "Always answer in rhymes." },
31+
{ "role": "user", "content": "Introduce yourself." }
32+
],
33+
"temperature": 0.7,
34+
"max_tokens": -1,
35+
"stream": true
36+
}'
3837
*/
3938

4039
var chatCompletionRequest = new ChatCompletionRequest(false, new[]
4140
{
42-
new Message("user", $"{_prompt}:\n\"{text}\""),
41+
new Message("user", $"{_prompt}:\n\n{text}"),
4342
new Message("system", "You are a helpful assistant.")
4443
}, 0.7);
4544

0 commit comments

Comments
 (0)