Parallel.ForEach x of x
因此,我正在使用c#4.0 WPF应用程序并使用并行foreach循环将数据导出到使用我创建的数据库存储库的数据库。我已经得到了使用进度条的并行foreach的出口工作,但希望能够给出更深入的进展细节,例如导出第25项中的第5项。我遇到的问题显而易见,因为它正在运行并行计数器不工作,即总量将这样说Parallel.ForEach x of x
exporting 0 of 25 exporting 0 of 25
...
exporting 5 of 25
exporting 5 of 25
谁能给如何获得行为的并行循环这样的范围内工作的任何指导做好:
int runningTotal = 0; Parallel.ForEach(source, x =>
{
Repository.Commit(x);
runningTotal++;
progressReporter.ReportProgress(() =>
{
//Progress bar update
this.progressFile.Value++;
this.lblProgress.Text = String
.Format("Exporting Source {0} of {1}", runningTotal, source.Count)
});
});
希望这显示了我希望达到的目标。
感谢
回答:
当你使用多个线程相同的数据,你应该保护它与锁定机构的访问。它可以通过使用lock
结构轻松完成。
但是,它可能有点太矫枉过正,以满足您的需求。由于您只是递增一个值,所以一个简单的System.Threading.Interlocked.Increment
就可以工作。在msdn上。
int runningTotal = 0; Parallel.ForEach(source, x =>
{
Repository.Commit(x);
Interlocked.Increment(ref runningTotal);
progressReporter.ReportProgress(() =>
{
//Progress bar update
Interlocked.Increment(ref this.progressFile.Value);
this.lblProgress.Text = String
.Format("Exporting Source {0} of {1}", runningTotal, source.Count)
});
});
编辑:我在WPF中做了一个示例。
Window.xaml:
<Window x:Class="WpfApplication4.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0" Click="Button_Click">Click me</Button>
<TextBlock Grid.Row="1">
<TextBlock.Text>
<MultiBinding StringFormat="Progress: {0}/{1}">
<Binding Path="ProgressValue" RelativeSource="{RelativeSource AncestorType=Window, Mode=FindAncestor}" />
<Binding Path="ProgressMax" RelativeSource="{RelativeSource AncestorType=Window, Mode=FindAncestor}" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Grid>
</Window>
Window.xaml.cs
public partial class MainWindow : Window, INotifyPropertyChanged {
public MainWindow()
{
InitializeComponent();
}
int progressValue;
public int ProgressValue
{
get { return (this.progressValue); }
set { this.progressValue = value; this.raisePropertyChanged("ProgressValue"); }
}
public int ProgressMax
{
get { return (100); }
}
public event PropertyChangedEventHandler PropertyChanged;
void raisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() =>
{
int counter = 0;
Parallel.ForEach(Enumerable.Range(1, 100), i =>
{
Interlocked.Increment(ref counter);
this.ProgressValue = counter;
Thread.Sleep(25);
});
});
}
}
我只是使用绑定来显示一个字符串,指示工作的进展情况。一切都存储在实现INotifyPropertyChanged
的窗口中,以强制绑定刷新并显示更新后的值。它可以很容易地移动到它自己的类,它将实现INotifyPropertyChanged
为更干净的代码。
以上是 Parallel.ForEach x of x 的全部内容, 来源链接: utcz.com/qa/260367.html