2
\$\begingroup\$

I have the following class:

public class IssueWithComments : Issue
{
    public IReadOnlyList<IssueComment> FullComments { get; set; }

    public IssueWithComments()
        : this(new List<IssueComment>())
    {
    }

    public IssueWithComments(IEnumerable<IssueComment> comments)
    {
        FullComments = comments.ToList();

    }

    public static IssueWithComments FromIssue(Issue issue, IEnumerable<IssueComment> comments)
    {
        return new IssueWithComments(comments) 
        {
            Assignee = issue.Assignee,
            Body = issue.Body,
            ClosedAt = issue.ClosedAt,
            Comments = issue.Comments,
            CreatedAt = issue.CreatedAt,
            HtmlUrl = issue.HtmlUrl,
            Labels = issue.Labels,
            Milestone = issue.Milestone,
            Number = issue.Number,
            PullRequest = issue.PullRequest,
            State = issue.State,
            Title = issue.Title,
            UpdatedAt = issue.UpdatedAt,
            Url = issue.Url,
            User = issue.User
        };
    }
}

where Issue is a type defined in the Octokit.Net namespace.

I populate my objects by calling the following code:

public static async Task<IReadOnlyList<IssueWithComments>> GetAllForRepositoryWithComments(this IIssuesClient client, string owner, string name)
{
     var issues = await client.GetAllForRepository(owner, name);
     List<IssueWithComments> all = new List<IssueWithComments>();

     foreach (var i in issues)
     {
         all.Add(IssueWithComments.FromIssue(i, await client.Comment.GetAllForIssue(owner, name, i.Number)));
     }

     return all;
 }

This works, but just takes 7.640 seconds on average according to System.Diagnostics.Stopwatch (plus that I can see it taking a long time to load).

Task.WhenAll could work, but the way to find the Issue it is referring to is as follows:

x.FullComments.First().HtmlUrl.Segments[4]

Is there a better way to either run the loop or should I go with Task.WhenAll and drill into the URL?

\$\endgroup\$
2
\$\begingroup\$

Since you're loading all comments for all issues, I think

await client.Comment.GetAllForRepository(owner, name)

is what you're looking for. Otherwise, if you do need to use GetAllForIssue, try using Task.WhenAll to run comments retrieval in parallel:

public static async Task<IReadOnlyList<IssueWithComments>> GetAllForRepositoryWithComments(IIssuesClient client, string owner, string name)
{
    var issues = await client.GetAllForRepository(owner, name);

    return await Task.WhenAll(issues.Select(async i => IssueWithComments.FromIssue(i, await client.Comment.GetAllForIssue(owner, name, i.Number)));
}
\$\endgroup\$
  • \$\begingroup\$ The first option would not work, as there is still no way to comfortably map the results to the appropriate issue. Your code - while very marginally slower then a fix I was working on - is much cleaner so you get the accept. \$\endgroup\$ – Mord Zuber Jun 8 '15 at 13:13
  • \$\begingroup\$ By the way this cuts it down from the 7.640 seconds mentioned in the question to an average if 1.5 seconds \$\endgroup\$ – Mord Zuber Jun 8 '15 at 13:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.