cAlgo API Http raises error when sending two or more requests

Created at 21 Mar 2025, 18:34
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
SO

soskrr

Joined 20.08.2023

cAlgo API Http raises error when sending two or more requests
21 Mar 2025, 18:34


Hi,

I am getting this error after this update, which is when I send two requests in a bot it will raise an error, with the following error message:

System.InvalidOperationException: This instance has already started one or more requests. Properties can only be modified before sending the first request.   at System.Net.Http.HttpClient.CheckDisposedOrStarted()   at System.Net.Http.HttpClient.set_Timeout(TimeSpan value)   at cTrader.Automate.Instances.Http.AutomateHttpService.RequestProcessor()

This started happening after the update. Am I doing something wrong or there's a bug?

using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class Test : Plugin
    {
        protected override void OnStart()
        {
            Test1();
            //Test2();
        }

        private void Test1()
        {
            HttpResponse res = Http.Get("https://jsonplaceholder.typicode.com/todos/2");
            if(res.IsSuccessful && res.StatusCode == 200)
            {
                Print(res.Body);
                MessageBox.Show(res.Body);
            }
            Sleep(5000);
            HttpResponse res2 = Http.Get("https://jsonplaceholder.typicode.com/todos/2");
            if(res2.IsSuccessful && res2.StatusCode == 200)
            {
                Print("Success2");
            } else 
            {
                MessageBox.Show(res2.Exception.ToString());
            }
        }

        private void Test2()
        {
            Http.GetAsync("https://jsonplaceholder.typicode.com/todos/2", res => 
            {
                if(res.IsSuccessful && res.StatusCode == 200)
                {
                    MessageBox.Show(res.Body);
                    Http.GetAsync("https://jsonplaceholder.typicode.com/todos/1", res2 => 
                    {
                        if(res.IsSuccessful && res2.StatusCode == 200)
                        {
                            MessageBox.Show(res2.Body);
                        } else {
                            MessageBox.Show(res2.Exception.ToString());
                        }
                    });
                }
            });
            Http.GetAsync("https://jsonplaceholder.typicode.com/todos/3", res => 
            {
                if(res.IsSuccessful && res.StatusCode == 200)
                {
                    MessageBox.Show(res.Body);
                } else {
                    MessageBox.Show(res.Exception.ToString());
                }
            });
        }

        protected override void OnStop()
        {
            // Handle Plugin stop here
        }
    }
}

Please help.

Thank you


@soskrr
Replies

edna23roe
22 Mar 2025, 05:34 ( Updated at: 28 Mar 2025, 04:42 )

This error typically occurs when you attempt to modify properties of an HttpClient instance (like Timeout) after it has already started processing requests. Once an HttpClient instance begins handling requests, its properties become immutable to ensure thread safety.

Here are some possible causes and solutions:

Reusing the Same HttpClient Instance:

If you're reusing the same HttpClient instance across multiple requests, ensure that you set all necessary properties (like Timeout) before sending the first request.

Solution: Create and configure the HttpClient instance once, and reuse it without modifying its properties.

Singleton Pattern Misuse:

If you're using a singleton HttpClient instance, ensure that its properties are configured only once during initialization.

Solution: Use dependency injection to manage the HttpClient lifecycle properly. For example, in .NET Core, you can register it as a singleton in the Startup class.

Creating a New Instance for Each Request:

If you're creating a new HttpClient instance for each request, this can lead to socket exhaustion and performance issues.

Solution: Use an IHttpClientFactory to manage HttpClient instances efficiently.

Timeout Configuration:

If you need to set a different timeout for specific requests, consider using a CancellationToken instead of modifying the Timeout property of the HttpClient.

Bug in the Update:

If this issue started after an update, it might be a regression or a change in how HttpClient is handled in the updated version.

Solution: Check the release notes or documentation for the update to see if there are any breaking changes. If you suspect a bug, consider reporting it to the maintainers of the library or framework you're using.

www-pikepass.com


@edna23roe

firemyst
23 Mar 2025, 02:15 ( Updated at: 28 Mar 2025, 07:58 )

How do we know if you're doing anything wrong when you haven't posted any sample code demonstrating what you are doing? Or you have posted code and it's still awaiting “moderation”? :-P


@firemyst

soskrr
23 Mar 2025, 08:16 ( Updated at: 24 Mar 2025, 07:00 )

RE: cAlgo API Http raises error when sending two or more requests

firemyst said: 

How do we know if you're doing anything wrong when you haven't posted any sample code demonstrating what you are doing?

using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class Test : Plugin
    {
        protected override void OnStart()
        {
            Test1();
            //Test2();
        }

        private void Test1()
        {
            HttpResponse res = Http.Get("https://jsonplaceholder.typicode.com/todos/2");
            if(res.IsSuccessful && res.StatusCode == 200)
            {
                Print(res.Body);
                MessageBox.Show(res.Body);
            }
            Sleep(5000);
            HttpResponse res2 = Http.Get("https://jsonplaceholder.typicode.com/todos/2");
            if(res2.IsSuccessful && res2.StatusCode == 200)
            {
                Print("Success2");
            } else 
            {
                MessageBox.Show(res2.Exception.ToString());
            }
        }

        private void Test2()
        {
            Http.GetAsync("https://jsonplaceholder.typicode.com/todos/2", res => 
            {
                if(res.IsSuccessful && res.StatusCode == 200)
                {
                    MessageBox.Show(res.Body);
                    Http.GetAsync("https://jsonplaceholder.typicode.com/todos/1", res2 => 
                    {
                        if(res.IsSuccessful && res2.StatusCode == 200)
                        {
                            MessageBox.Show(res2.Body);
                        } else {
                            MessageBox.Show(res2.Exception.ToString());
                        }
                    });
                }
            });
            Http.GetAsync("https://jsonplaceholder.typicode.com/todos/3", res => 
            {
                if(res.IsSuccessful && res.StatusCode == 200)
                {
                    MessageBox.Show(res.Body);
                } else {
                    MessageBox.Show(res.Exception.ToString());
                }
            });
        }

        protected override void OnStop()
        {
            // Handle Plugin stop here
        }
    }
}

Here's the code.


@soskrr

ctid8068054
28 Mar 2025, 01:05 ( Updated at: 28 Mar 2025, 07:17 )

RE: RE: cAlgo API Http raises error when sending two or more requests

soskrr said: 

firemyst said: 

How do we know if you're doing anything wrong when you haven't posted any sample code demonstrating what you are doing?

using System;using cAlgo.API;using cAlgo.API.Collections;using cAlgo.API.Indicators;using cAlgo.API.Internals;namespace cAlgo.Plugins{    [Plugin(AccessRights = AccessRights.None)]    public class Test : Plugin    {        protected override void OnStart()        {            Test1();            //Test2();        }        private void Test1()        {            HttpResponse res = Http.Get("https://jsonplaceholder.typicode.com/todos/2");            if(res.IsSuccessful && res.StatusCode == 200)            {                Print(res.Body);                MessageBox.Show(res.Body);            }            Sleep(5000);            HttpResponse res2 = Http.Get("https://jsonplaceholder.typicode.com/todos/2");            if(res2.IsSuccessful && res2.StatusCode == 200)            {                Print("Success2");            } else             {                MessageBox.Show(res2.Exception.ToString());            }        }        private void Test2()        {            Http.GetAsync("https://jsonplaceholder.typicode.com/todos/2", res =>             {                if(res.IsSuccessful && res.StatusCode == 200)                {                    MessageBox.Show(res.Body);                    Http.GetAsync("https://jsonplaceholder.typicode.com/todos/1", res2 =>                     {                        if(res.IsSuccessful && res2.StatusCode == 200)                        {                            MessageBox.Show(res2.Body);                        } else {                            MessageBox.Show(res2.Exception.ToString());                        }                    });                }            });            Http.GetAsync("https://jsonplaceholder.typicode.com/todos/3", res =>             {                if(res.IsSuccessful && res.StatusCode == 200)                {                    MessageBox.Show(res.Body);                } else {                    MessageBox.Show(res.Exception.ToString());                }            });        }        protected override void OnStop()        {            // Handle Plugin stop here        }    }}

Here's the code.

 

Also suffering the same fate.  I can't see any dif between the two code blocks above.  No solution for me as yet.  

 


@ctid8068054