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

回到顶部