vdemydiuk / mtapi

MetaTrader API (terminal bridge)
http://mtapi4.net/
MIT License
524 stars 283 forks source link

MtApi.MtExecutionException: 'Response from MetaTrader is null' #249

Open zemuss opened 3 years ago

zemuss commented 3 years ago

MtApi.MtExecutionException HResult=0x80131500 Message=Response from MetaTrader is null Source=MtApi StackTrace: at MtApi.MtApiClient.SendCommand[T](MtCommandType commandType, ArrayList commandParameters, Dictionary`2 namedParams) in \MtApi\MtApiClient.cs:line 3063

zemuss commented 3 years ago

In order to get the application working again I have to relaunch mt4.

lazou commented 3 years ago

This does also occur sometimes with mt5, but often due to invalid api calls. For example when a parallel call did lead to a disconnect which then results in your mentioned exception. So, the issue is maybe not located in your api call, instead somewhere else.

zemuss commented 3 years ago

Ok I used the client GUI that comes with the solution as my starting point and modified as needed. I never really understood why you need to have a chart for each symbol and mtapi ea on each chart. Seems like we can reduce traffic by using a collection send symbols get current bids and asks back in a xml doc.

zemuss commented 3 years ago

More details: System.ServiceModel.CommunicationException HResult=0x80131501 Message=The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error. Source=mscorlib StackTrace: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at MTApiService.IMtApi.SendCommand(MtCommand command) at MTApiService.MtApiProxy.SendCommand(MtCommand command) in \MTApiService\MtApiProxy.cs:line 31

This exception was originally thrown at this call stack: [External Code] MTApiService.MtApiProxy.SendCommand(MTApiService.MtCommand) in MtApiProxy.cs

jdufaud commented 3 years ago

I have a fix for you, use a lock in the Execute method. If you are making a lot of call at the same time this exception can bell called

private static readonly object objLock = new object();

private static async Task<TResult> Execute<TResult>(Func<TResult> func)
{
            return await Task.Factory.StartNew(() =>
            {
                lock(objLock)
                {
                    var result = default(TResult);
                    try
                    {
                        result = func();
                    }
                    catch (ExecutionException ex)
                    {
                        Console.WriteLine($"Exception: {ex.ErrorCode} - {ex.Message}");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Exception: {ex.Message}");
                    }
                    return result;
                }
            });
}