Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Source coming from multiple threads? #44

Open
ejlevin1 opened this issue May 19, 2019 · 1 comment
Open

Source coming from multiple threads? #44

ejlevin1 opened this issue May 19, 2019 · 1 comment

Comments

@ejlevin1
Copy link

Is the sourcing of the stream thread safe? I.e. would the below situation cause any issues I'm unaware of. I have a situation where I need to make a large amount of async requests that generate the async stream, and want to do the sourcing requests in parallel (unordered), and then push into the async stream. Will that create any negative side effects I'm not seeing?

[Fact]
        public void TestAsyncStreams()
        {
            IList<string> urls = new List<string>() {
                "http://www.google.com",
                "http://www.microsoft.com",
                "http://www.github.com"
            };


            var result = new ConcurrentBag<string>();

            var asyncEnumerableCollection = ProduceWebPages(urls, CancellationToken.None);
            asyncEnumerableCollection.ForEachAsync(async page => {
                result.Add(page);
            }).Wait();

            Assert.Equal(urls.Count, result.Count);
        }

        static IAsyncEnumerable<string> ProduceWebPages(IEnumerable<string> urls, CancellationToken cancellationToken)
        {
            return new AsyncEnumerable<string>(async yield => {

                await urls.ParallelForEachAsync(
                    async uri =>
                    {
                        using (var client = new HttpClient())
                        {
                            var str = await client.GetStringAsync(uri);
                            await yield.ReturnAsync(str);
                        }
                    },
                    maxDegreeOfParalellism: 5,
                    cancellationToken: cancellationToken);

                Console.WriteLine("Done");
            });
        }
@kind-serge
Copy link
Member

kind-serge commented May 28, 2019

@ejlevin1, the yield.Return is not thread-safe, so the sample code certainly leads to an unpredicted behavior.

Having multiple producers and one (or multiple) consumers is a slightly more complex problem, which is discussed in issue #32.

I posted an example on StackOverflow how to implement it:
https://stackoverflow.com/questions/54402544/c-sharp-asyncenumerable-running-awaiting-multiple-tasks-never-finishes/56189780#56189780

It seems that the solution to this problem can be a good candidate for a helper/extension method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants