Возникновение ошибки PInvoke при подключении к PLAZA2
При попытке запустить простенькое приложение на тестовой плазе, замеряющее раундтрипы, возникает следующая ошибка:
Fatal Execution Engine Error
В среде выполнения обнаружена критическая ошибка. Ошибка произошла по адресу 0x62f730c8 в потоке 0x2154. Код ошибки 0xc0000005. Она может быть вызвана ошибкой в CLR или в небезопасных либо не поддающихся проверке фрагментах пользовательского кода. Обычно источниками таких ошибок бывают ошибки упаковки, допускаемые пользователями при COM-взаимодействии, либо PInvoke, повредивший стек.
Это же приложение работает при подключении к квику, а также другое приложение на PLAZA2 работает с точно таким же PlazaTrader'ом. Помогите, пожалуйста, разобраться, что это такое. Падение происходит на trader.Connect().
Вот сам код приложения:
Code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mime;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Ecng.Collections;
using Ecng.Common;
using StockSharp.BusinessEntities;
using StockSharp.Logging;
using StockSharp.Algo;
using StockSharp.Plaza;
using StockSharp.Quik;
using StockSharp.Algo.Strategies;
namespace SpeedTestConsole //Код со всеми комментариями, которые мы в последний раз оставили.
{
public delegate void ExitHandler();
internal class Program
{
public static RoundStrategy strat;
public static PlazaTrader trader
= new PlazaTrader
{
Address = "127.0.0.1:4001".To<IPEndPoint>(),
UseLocalProtocol = true,
IsCGate = true,
PollTimeOut = TimeSpan.FromMilliseconds(0.1),
Login = string.Empty,
Password = string.Empty,
AppName="SS_1"
};
private static void Main()
{
Security security = null;
Portfolio portfolio = null;
trader.Connected += trader.StartExport;
trader.NewSecurities += securities =>
{
if (security != null)
return;
foreach (var s in securities.Where(s => s.Id == "RIZ3@RTS")) //"SBER@QJSIM"))
{
Console.WriteLine("Инструмент загружен: " + s);
security = s;
trader.RegisterMarketDepth(security);
}
};
trader.NewPortfolios += portfolios =>
{
if (portfolio != null)
return;
foreach (var p in portfolios.Where(p => p.Name == "FZ00A56"))//"64597"))
{
Console.WriteLine("Портфель загружен: " + p);
portfolio = p;
}
};
trader.OrdersCancelFailed += fails =>
{
foreach (var orderFail in fails)
Console.WriteLine(orderFail.Error.Message);
};
trader.OrdersRegisterFailed += fails =>
{
foreach (var orderFail in fails)
Console.WriteLine(orderFail.Error.Message);
};
trader.ConnectionError += exception =>
{
Console.WriteLine(exception.Message);
Console.ReadLine();
};
trader.Connect();
Console.WriteLine("Дождитесь, когда загрузятся инструмент и портфель, затем начните тестирование.");
Console.ReadLine();
strat = new RoundStrategy
{
Trader = trader,
Portfolio = portfolio,
Security = security
};
strat._exit += Exit;
strat.Start();
Thread.Sleep(15000);
}
public static void Exit()
{
Console.WriteLine("Отправка заявок завершена.");
strat.Stop();
trader.StopExport();
trader.Dispose();
Console.Read();
}
}
public class RoundStrategy:Strategy
{
public event ExitHandler _exit;
public void OrderMaking(int i)
{
if (i >= 5)
{
if (_exit != null)
_exit();
return;
}
var market = Trader.GetMarketDepth(Security);
var o = new Order
{
Price = Security.ShrinkPrice(market.BestBid.Price * (1 - 0.01M)),
Direction = OrderDirections.Buy,
Volume = 1,
Security = Security,
Portfolio = Portfolio,
Trader = Trader,
};
Rule(o,i);
RegisterOrder(o);
}
protected override void OnStarted()
{
OrderMaking(0);
}
public void Rule(Order order, int i)
{
order
.WhenRegistered()
.Do(() =>
{
Console.WriteLine("Время постановки = {0}", order.LatencyRegistration.TotalMilliseconds);
CancelOrder(order);
})
.Once()
.Apply(this);
order.WhenCanceled()
.Do(() =>
{
Console.WriteLine("Время снятия = {0}", order.LatencyCancellation.TotalMilliseconds);
OrderMaking(i+1);
}).Once()
.Apply(this);
}
}
}