Goroutine循环未完成

Goroutine循环未完成,go,goroutine,Go,Goroutine,我试图在数组中循环并复制数组中的每个值。我只想在一个单独的goroutine中旋转每个循环。当我使用goroutine运行它时,它将循环一个小于数组大小的循环(len(array)-1),但是如果我去掉goroutine,那么它的处理就很好了 我是否遗漏了一些关于这应该如何工作的信息?运行goroutines时总是少一个,这似乎很奇怪。下面是我的代码 func createEventsForEachWorkoutReference(plan *sharedstructs.Plan, user *

我试图在数组中循环并复制数组中的每个值。我只想在一个单独的goroutine中旋转每个循环。当我使用goroutine运行它时,它将循环一个小于数组大小的循环(len(array)-1),但是如果我去掉goroutine,那么它的处理就很好了

我是否遗漏了一些关于这应该如何工作的信息?运行goroutines时总是少一个,这似乎很奇怪。下面是我的代码

func createEventsForEachWorkoutReference(plan *sharedstructs.Plan, user *sharedstructs.User, startTime time.Time, timeZoneKey *string, transactionID *string, monitoringChannel chan interface{}) {
    //Set the activity type as these workouts are coming from plans
    activityType := "workout"
    for _, workoutReference := range plan.WorkoutReferences {
        go func(workoutReference sharedstructs.WorkoutReference) {
            workout, getWorkoutError := workout.GetWorkoutByName(workoutReference.WorkoutID.ID, *transactionID)
            if getWorkoutError == nil && workout != nil {
                //For each workout, create a reference to be inserted into the event
                reference := sharedstructs.Reference{ID: workout.WorkoutID, Type: activityType, Index: 0}
                referenceArray := make([]sharedstructs.Reference, 0)
                referenceArray = append(referenceArray, reference)
                event := sharedstructs.Event{
                    EventID:       uuidhelper.GenerateUUID(),
                    Description:   workout.Description,
                    Type:          activityType,
                    UserID:        user.UserID,
                    IsPublic:      false,
                    References:    referenceArray,
                    EventDateTime: startTime,
                    PlanID:        plan.PlanID}
                //Insert the Event into the databse, I don't handle errors intentionally as it will be async
                creationError := eventdomain.CreateNewEvent(&event, transactionID)
                if creationError != nil {
                    redFalconLogger.LogCritical("plan.createEventsForEachWorkoutReference() Error Creating a workout"+creationError.Error(), *transactionID)
                }
                //add to the outputchannel
                monitoringChannel <- event
                //Calculate the next start time for the next loop
                startTime = calculateNextEventTime(&startTime, &workoutReference.RestTime, timeZoneKey, transactionID)
            }
        }(workoutReference)
    }
    return
}
想再添加一个示例(没有我的自定义代码)。你可以注释掉sleep行,看看它是否与sleep一起工作


终于找到了答案

问题是,我需要在第一个goroutine中关闭monitoringChan,然后在第二个goroutine中关闭monitor(Defer wg.close())。当我这么做的时候,工作非常好


尽量给出满足您需求的最小示例,不要只是从项目中复制和粘贴代码。可能重复的代码我感谢您的帮助,我尝试在循环中使用Wg.Wait(),但似乎没有帮助。当我把它放在goroutine中时,它不会处理循环中的每一项,但当我同步时,它就会处理。很明显,我遗漏了一些关于goroutines是如何工作的。我会继续尝试其他事情。我已经找到了根本原因,但还不知道解决办法。我的调用函数在goroutine中运行其处理,并在chan(接口{}类型)上“侦听”。它是在成龙真正更新之前完成最后一个循环并返回。因此,在调用goroutine完成之前,最后一项的chan处理没有完成。是否有其他方法(time.Sleep()除外)确保chan处理完成?我会将代码发布到OP。
var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    createEventsForEachWorkoutReference(plan, &returnedUser, startDate, &timeZone, &transactionID, monitoringChan)
}()
var userEventArrayList []sharedstructs.Event
go func() {
    for result := range monitoringChan {
        switch result.(type) {
        case sharedstructs.Event:
            counter++
            event := result.(sharedstructs.Event)
            userEventArrayList = append(userEventArrayList, event)
            fmt.Println("Channel Picked Up New Event: " + event.EventID + " with counter " + strconv.Itoa(counter))
        default:
            fmt.Println("No Match")
        }
    }
}()
wg.Wait()
//I COULD SLEEP HERE BUT THAT SEEMS HACKY
close(monitoringChan)