我正在为我的项目创建批处理编码器。它是这样的:(我只需要在每个项目中添加取消按钮并替换占位符)
对于添加的每个项目,线程/任务应处理给定的信息(图像)并作为编码图像保存在磁盘上。
我习惯使用delegate
和delegateObject.BeginInvoke(...)
,但我只使用static
方法中的delegate
次调用更新了用户界面。
我使用WinForms
执行此操作,而不是使用动态的项目列表。
另外,我不熟悉从UI中取消线程/任务。
我需要一点努力才能找到解决这个问题的最佳方法。
如何管理多个并行操作并更新UI?
答案 0 :(得分:1)
您是否看过使用取消令牌?有点像:
private CancellationTokenSource _cts;
private async void start_Click(object sender, EventArgs e)
{
_cts = new CancellationTokenSource();
var token = _cts.Token;
try
{
await Task.Run(() =>
{
// Your encoding process
});
}
catch (OperationCanceledException)
{
// Handle cancellation
}
}
private void stop_Click(object sender, EventArgs e)
{
if (_cts != null)
_cts.Cancel();
}
答案 1 :(得分:0)
这是工作代码。它将并排运行编码过程,如果使用InternalUpdate
的正确ID调用Task
方法,则会更新UI。
int a = 0;
var context = TaskScheduler.FromCurrentSynchronizationContext();
var task = new Task(() =>
{
Encode(listFrames, a);
},
_cancellationToken.Token);
//Unique ID.
a = task.Id;
//Adds the item to the list.
var encoderItem = new EncoderListViewItem
{
Image = (UIElement)Resources["Image"],
Text = "Starting",
Percentage = 0,
Id = a
};
EncodingListBox.Items.Add(encoderItem);
_taskList.Add(task);
_taskList.Last().Start();
更新每个项目:
private void InternalUpdate(int id, double percentagem, string status)
{
this.Dispatcher.Invoke(() =>
{
var item = EncodingListBox.Items.Cast<EncoderListViewItem>().FirstOrDefault(x => x.Id == id);
if (item != null)
{
item.Percentage = percentagem;
item.Text = status;
}
});
}