Illegal call out of MainThread is detected. Use `BeginInvokeOnMainThread`
Illegal call out of MainThread is detected. Use `BeginInvokeOnMainThread`
13 May 2022, 14:21
All of our products at ClickAlgo use a standard threading model to open a UI form as shown below, this has been working fine for many years.
cTrader Desktop 4.2 Beta
try
{
thread = new Thread(() =>
{
try
{
bootStrap = new Bootstrap(this);
System.Windows.Forms.Application.Run(bootStrap.mainPanel);
}
catch
{
}
});
thread.SetApartmentState(ApartmentState.MTA);
thread.IsBackground = true;
thread.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
this.Stop();
}
The only difference was that we were using an STA thread.
Now with cTrader Desktop 4.2, a warning is thrown stating that it is an illegal call out from the main thread and that we need to now use BeginInvokeOnMainThread
Is this now the only option we have for spawning a user interface?
A test using the new method is shown below which works fine, but there is an issue with events from the robot object passed across.
BeginInvokeOnMainThread(() =>
{
try
{
bootStrap = new Bootstrap(this);
System.Windows.Forms.Application.Run(bootStrap.mainPanel);
}
catch
{
}
});
I understand the warning, but does this mean we need to update all of our products to suppress this warning?
UPDATE
If the BeginInvokeOnMainThread method is used and a Robot object is passed in, many events are not working or work sometimes like closing positions Async.
Replies
ClickAlgo
16 May 2022, 12:34
I have found the offending code that is causing this error, this will happen to a few of our products.
Leverage = robot.Account.PreciseLeverage
The robot object is passed into the assembly class that displays the UI, all the other events work fine, but when a call is made to retrieve account information, it throws the error below.
Illegal call out of MainThread is detected. Use `BeginInvokeOnMainThread`
@ClickAlgo
lisabeaney
16 May 2022, 14:03
RE:
I'm having the same problem so will follow this thread with interest !
ClickAlgo said:
I have found the offending code that is causing this error, this will happen to a few of our products.
Leverage = robot.Account.PreciseLeverage
The robot object is passed into the assembly class that displays the UI, all the other events work fine, but when a call is made to retrieve account information, it throws the error below.
Illegal call out of MainThread is detected. Use `BeginInvokeOnMainThread`
@lisabeaney
amusleh
16 May 2022, 14:23
Hi,
The warning message is there for notifying the user that the way h is using API is not correct, and the API calls should be made only from cBot/Indicator main thread not other threads.
For anyone who face same warning, we recommend you to use the BeginInvokeOnMainThread when you are using API members from other thread, that's the right way, otherwise you can face deadlocks or race condition.
Automate API is not thread safe, it should be only accessed via cBot/Indicator main thread, when you are using multiple threads dispatch the calls to API members to main cBot/Indicator thread for avoiding any inconsistency.
You can use decorator pattern, create a derived class from Robot or Indicator base classes, override all members to dispatch the calls to main thread by using BeginInvokeOnMainThread method.
@amusleh
ClickAlgo
16 May 2022, 16:36
( Updated at: 17 May 2022, 11:58 )
Ahmad, is correct, we should be implementing the calls with more grace, the following call fixes the warning messages and works fine with CT 4.2
private void btnReverseSellers_Click(object sender, EventArgs e)
{
_robot.BeginInvokeOnMainThread(() =>
{
try
{
foreach (var position in _robot.Positions.Where(x => (x.SymbolName == _robot.Symbol.Name)).Where(x => x.TradeType == TradeType.Sell))
{
position.Reverse();
}
}
catch (Exception ex)
{
AlertPopUp msg = new Orders.AlertPopUp(ex.Message);
msg.Show();
}
});
}
@ClickAlgo
amusleh
16 May 2022, 10:44 ( Updated at: 16 May 2022, 10:45 )
Hi,
I'm not exactly sure what warning you are facing, this works fine for me:
Regarding some events not working properly, in version 4.2 any API call must be executed from the main cBot/Indicator thread, you can't call a cBot/Indicator method/property from another thread, dispatch the call to main thread by using BeginInvokeOnMainThread method.
Please read our new guide for WinForms: WinForms - cTrader Automate API Documentation (spotware.github.io)
@amusleh