locked
Parallel.ForEach hangs WCF Data Service RRS feed

  • Question

  • Using Parallel.ForEach to parse files in a WCF Data Service seems to cause the service to hang.
    A squential loop works fin.
    The same Parallel loop works fine in a console app.

        Shared _messungen As New List(Of Messung)
    
        Shared Sub New()
                Dim fileNames = Directory.GetFiles("c:\temp\00_MessungenFiles")
    
                'Sequential loop
                'For Each fileName In fileNames
                '    LoadMessungFile(fileName)
                'Next
    
                'Parallel loop
                Parallel.ForEach(fileNames, Sub(fileName As String)
                                               LoadMessungFile(fileName)
                                           End Sub)
        End Sub
    
        Shared Sub LoadMessungFile(ByVal fileName As String)
            Dim xml = XElement.Load(fileName)
            Dim messung As New Messung
            messung.MessungNr = Integer.Parse(xml.Element("MessungsNr").Value.ToString)
            messung.Pruefer = xml.Element("Pruefer").Value.ToString
            messung.Datum = Date.Parse(xml.Element("Datum").Value.ToString)
            messung.Uhrzeit = xml.Element("Uhrzeit").Value.ToString
            messung.GetriebeNr = xml.Element("GetriebeNr").Value.ToString
            messung.SetupId = xml.Element("SetUpId").Value.ToString
            _messungen.Add(messung)
        End Sub
    Thursday, March 4, 2010 8:56 AM

Answers

  • I just tried this, creating a new WCF Service application, adding to it a new WCF Data Service, and pasting in your code instead of the default code for that .svc.  I then did View in Browser on the .svc, both for the sequential loop and for the parallel loop.  Both succeeded, showing the following in the browser:

    <?
    xml version="1.0" encoding="utf-8" standalone="yes" ?>
    <service xml:base="http://localhost:17382/WcfDataService1.svc/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app">
        <workspace>
            <atom:title>Default</atom:title>
            <collection href="Messungen">
                <atom:title>Messungen</atom:title>
            </collection>
        </workspace>
    </service>
    Tuesday, March 9, 2010 5:16 PM
    Moderator

All replies

  • I don't see anything in this, directly, that would cause a "hang".  I recommend running this under VS 2010 RC, and pausing when it hangs.  You should be able to look at the Parallel Tasks and Parallel Stacks debugging windows, and see where your code is hanging.  Once you know where it's hanging, it will most likely be easy to correct.

    That being said, there is a bug in your code above.  List(Of T) is not threadsafe, so you need to add locking where you're calling Add on the _messungen list:

        Shared _messungen As New List(Of Messung)
        Shared _lockObj As New Object()
    
        Shared Sub New()
                Dim fileNames = Directory.GetFiles("c:\temp\00_MessungenFiles")
    
                'Sequential loop
                'For Each fileName In fileNames
                '    LoadMessungFile(fileName)
                'Next
    
                'Parallel loop
                Parallel.ForEach(fileNames, Sub(fileName As String)
                                               LoadMessungFile(fileName)
                                           End Sub)
        End Sub
    
        Shared Sub LoadMessungFile(ByVal fileName As String)
            Dim xml = XElement.Load(fileName)
            Dim messung As New Messung
            messung.MessungNr = Integer.Parse(xml.Element("MessungsNr").Value.ToString)
            messung.Pruefer = xml.Element("Pruefer").Value.ToString
            messung.Datum = Date.Parse(xml.Element("Datum").Value.ToString)
            messung.Uhrzeit = xml.Element("Uhrzeit").Value.ToString
            messung.GetriebeNr = xml.Element("GetriebeNr").Value.ToString
            messung.SetupId = xml.Element("SetUpId").Value.ToString
    
            ' Add a lock here!
            SyncLock _lockObj
                _messungen.Add(messung)
            End SyncLock
        End Sub


    Reed Copsey, Jr. - http://reedcopsey.com
    Thursday, March 4, 2010 4:20 PM
    Moderator
  • I am using VS2010RC.

    My Service hangs as soon as I put in the Parallel.ForEach. Even when commenting out all code in the Sub LoadMessungFile.
    It does not even enter InitializeService. 

    I will build a small test case as soon as I have time.
    Thursday, March 4, 2010 8:05 PM
  • Here a small complete test case demonstrating the hang.
    View in Browser with Parallel.ForEach hangs.

    Imports System.Data.Services
    Imports System.Data.Services.Common
    Imports System.Linq
    Imports System.ServiceModel.Web
    Imports System.IO
    Imports System.Threading.Tasks
    
    <DataServiceKeyAttribute("MessungNr")>
    Public Class Messung
        Public Property MessungNr() As Integer
    End Class
    
    Public Class MessungFilesEntities
        Shared _messungen As New Concurrent.ConcurrentBag(Of Messung)
    
        Public ReadOnly Property Messungen() As IQueryable(Of Messung)
            Get
                Return _messungen.AsQueryable
            End Get
        End Property
    
        Shared Sub New()
            Dim fileNames = Directory.GetFiles("c:\temp\00_MessungenFiles")
    
            'Sequential loop
            'For Each fileName In fileNames
            '    LoadMessungFile(fileName)
            'Next
    
            'Parellel loop
            Parallel.ForEach(fileNames, Sub(fileName As String)
                                            LoadMessungFile(fileName)
                                        End Sub)
        End Sub
    
        Shared Sub LoadMessungFile(ByVal fileName As String)
            Dim xml = XElement.Load(fileName)
            Dim messung As New Messung
            messung.MessungNr = Integer.Parse(xml.Element("MessungsNr").Value.ToString)
            _messungen.Add(messung)
        End Sub
    End Class
    
    <System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults:=True)>
    Public Class WcfDataService1
        'Inherits DataService(Of OrderItemData)
        Inherits DataService(Of MessungFilesEntities)
    
        Public Shared Sub InitializeService(ByVal config As DataServiceConfiguration)
            config.SetEntitySetAccessRule("*", EntitySetRights.AllRead)
            config.SetServiceOperationAccessRule("*", ServiceOperationRights.All)
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2
            config.UseVerboseErrors = True
        End Sub
    
    End Class
    
    
    Saturday, March 6, 2010 7:25 AM
  • I just tried this, creating a new WCF Service application, adding to it a new WCF Data Service, and pasting in your code instead of the default code for that .svc.  I then did View in Browser on the .svc, both for the sequential loop and for the parallel loop.  Both succeeded, showing the following in the browser:

    <?
    xml version="1.0" encoding="utf-8" standalone="yes" ?>
    <service xml:base="http://localhost:17382/WcfDataService1.svc/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app">
        <workspace>
            <atom:title>Default</atom:title>
            <collection href="Messungen">
                <atom:title>Messungen</atom:title>
            </collection>
        </workspace>
    </service>
    Tuesday, March 9, 2010 5:16 PM
    Moderator
  • I tried my sample on a different machine and there it does not hang.

    I posted this problem because I supected a bug in VS2010.
    Now it looks more like some strange config of one of my machines.

    We can close this thread.


    Tuesday, March 16, 2010 6:38 PM