Parallel.ForEach 和 DataGridViewRow
Parallel.ForEach and DataGridViewRow
我在将 .AsParallel
转换为 Parallel.ForEach
时遇到问题。
我有一个 DataGridView
并且我在它的第一列中放置了一些值然后使用 ForEach
循环我将值发送到方法并获得一个 return 值然后我' m 将 return 值放到第二列。
开头;我正在使用 ForEach
循环,但它需要太多时间,然后我决定使用 .AsParallel
但我认为,在我的情况下,使用 Parallel.ForEach
可能更好,但我不能'无法与 datagridviewrow
.
一起使用
ForEach 方法:
foreach (DataGridViewRow dgvRow in dataGrid1.Rows)
{
// SOME CODES REMOVED FOR CLARITY
string data1 = row.Cells[1].Value;
var returnData = getHtml(data1);
row.Cells[2].Value = returnData;
}
AsParallel 方法:
dataGrid1.Rows.Cast<DataGridViewRow>().AsParallel().ForAll(row =>
{
// SOME CODES REMOVED FOR CLARITY
string data1 = row.Cells[1].Value;
var returnData = getHtml(data1);
row.Cells[2].Value = returnData;
});
那么,我如何将 Parallel.ForEach
循环与 DataGridViewRow
(DataGridView) 一起使用?
谢谢。
如果 getHtml
(以及循环的其他非 UI 部分)相对昂贵,那么并行执行您尝试执行的操作是有意义的,如果它很便宜那么并行执行它是没有意义的,因为更新 UI (您的数据网格)无论如何都需要顺序,因为只有 UI 线程可以更新它。
如果 getHtml
(和其他非 UI 循环部分)相对昂贵,您可以执行以下操作:
var current_synchronization_context = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() => //This is important to make sure that the UI thread can return immediately and then be able to process UI update requests
{
Parallel.ForEach(dataGrid1.Rows.Cast<DataGridViewRow>(), row =>
{
// SOME CODES REMOVED FOR CLARITY
string data1 = row.Cells[1].Value;
var returnData = getHtml(data1); //expensive call
Task.Factory.StartNew(() => row.Cells[2].Value = returnData,
CancellationToken.None,
TaskCreationOptions.None,
current_synchronization_context); //This will request a UI update on the UI thread and return immediately
});
});
创建 Task
并使用 TaskScheduler.FromCurrentSynchronizationContext()
将在 Windows Forms 应用程序和 WPF 应用程序中工作。
如果您不想为每个 UI 更新安排一个任务,您可以像这样直接调用 BeginInvoke 方法(如果这是一个 Windows 表单应用程序):
dataGrid1.BeginInvoke((Action)(() =>
{
row.Cells[2].Value = returnData;
}));
我上面的建议将导致数据呈现到 UI,因为它是 processed/generated。
如果您不关心这个,并且您可以先处理所有数据然后更新 UI,那么您可以执行以下操作:
1) 在 UI 线程
中收集来自 UI 的所有数据
2) 通过 Parallel.ForEach 处理该数据并将结果存储在数组中
3) 将数据从 UI 线程
渲染到 UI
我在将 .AsParallel
转换为 Parallel.ForEach
时遇到问题。
我有一个 DataGridView
并且我在它的第一列中放置了一些值然后使用 ForEach
循环我将值发送到方法并获得一个 return 值然后我' m 将 return 值放到第二列。
开头;我正在使用 ForEach
循环,但它需要太多时间,然后我决定使用 .AsParallel
但我认为,在我的情况下,使用 Parallel.ForEach
可能更好,但我不能'无法与 datagridviewrow
.
ForEach 方法:
foreach (DataGridViewRow dgvRow in dataGrid1.Rows)
{
// SOME CODES REMOVED FOR CLARITY
string data1 = row.Cells[1].Value;
var returnData = getHtml(data1);
row.Cells[2].Value = returnData;
}
AsParallel 方法:
dataGrid1.Rows.Cast<DataGridViewRow>().AsParallel().ForAll(row =>
{
// SOME CODES REMOVED FOR CLARITY
string data1 = row.Cells[1].Value;
var returnData = getHtml(data1);
row.Cells[2].Value = returnData;
});
那么,我如何将 Parallel.ForEach
循环与 DataGridViewRow
(DataGridView) 一起使用?
谢谢。
如果 getHtml
(以及循环的其他非 UI 部分)相对昂贵,那么并行执行您尝试执行的操作是有意义的,如果它很便宜那么并行执行它是没有意义的,因为更新 UI (您的数据网格)无论如何都需要顺序,因为只有 UI 线程可以更新它。
如果 getHtml
(和其他非 UI 循环部分)相对昂贵,您可以执行以下操作:
var current_synchronization_context = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() => //This is important to make sure that the UI thread can return immediately and then be able to process UI update requests
{
Parallel.ForEach(dataGrid1.Rows.Cast<DataGridViewRow>(), row =>
{
// SOME CODES REMOVED FOR CLARITY
string data1 = row.Cells[1].Value;
var returnData = getHtml(data1); //expensive call
Task.Factory.StartNew(() => row.Cells[2].Value = returnData,
CancellationToken.None,
TaskCreationOptions.None,
current_synchronization_context); //This will request a UI update on the UI thread and return immediately
});
});
创建 Task
并使用 TaskScheduler.FromCurrentSynchronizationContext()
将在 Windows Forms 应用程序和 WPF 应用程序中工作。
如果您不想为每个 UI 更新安排一个任务,您可以像这样直接调用 BeginInvoke 方法(如果这是一个 Windows 表单应用程序):
dataGrid1.BeginInvoke((Action)(() =>
{
row.Cells[2].Value = returnData;
}));
我上面的建议将导致数据呈现到 UI,因为它是 processed/generated。
如果您不关心这个,并且您可以先处理所有数据然后更新 UI,那么您可以执行以下操作:
1) 在 UI 线程
中收集来自 UI 的所有数据2) 通过 Parallel.ForEach 处理该数据并将结果存储在数组中
3) 将数据从 UI 线程
渲染到 UI