IvanB:
Bond:
Просто включаю и выключаю коннектор к Квику. И с каждым перезапуском он все тяжелее загружает данные, а потом на 4-5 включении выбрасывает с ошибкой о переполнении памяти. С каждым включением он съедает 400 Мб оперативной памяти, а после отключения её не выгружает. Только когда закрываешь окно коннектора он освобождает память. Код отключения у меня как из уроков:
public void DisConnectSafe()
{
//Если коннектор к торговой платформе не пуст и соединение установлено
if(Trader!=null && Trader.IsConnected)
{
Trader.StopExport();
Trader.Disconnect();
}
}
> > Dispose() не помогает!!!
> Убедитесь, что DisConnectSafe вызывается при отключении коннектора, и если в обычном виде (код выше) мусор из памяти не освобождается, то сделайте так:
> ```csharp
public void DisConnectSafe()
{
//Если коннектор к торговой платформе не пуст и соединение установлено
if(Trader!=null)
{
if (Trader.IsConnected)
{
Trader.StopExport();
Trader.Disconnect();
}
Trader.Dispose();
Trader=null;
GC.Collect();
}
}
Эффекта 0! При пошаговой проверке оказалось, что после Trader.Disconnect(), Trader.Dispose(), GC.Collect() память уменьшается на 10-20Мбайт не более, а вся прога жрет под 300Мбайт.
А при Trader=null; при повторном запуске при нажатии на кнопку вылетает по Эксепшену. И правильно на мой взгляд делает. Вообще эту строку закомментил.
Может не освобождает потому, что Trader где-то ещё используется? Я к сожалению в тонкостях не разбираюсь...
using System;
using System.IO;
using System.Linq;
using Ecng.Collections;
using StockSharp.Algo;
using StockSharp.BusinessEntities;
using StockSharp.Quik;
namespace StockSharp.TraderConnection
{
/// <summary>
/// Безопасное подключение
/// </summary>
public class SafeConnection
{
/// <summary>
/// Коннектор к торговой платформе
/// </summary>
public BaseTrader Trader { get; private set; }
/// <summary>
/// Событие появления нового исключения
/// </summary>
public event Action<Exception> NewException = delegate { };
/// <summary>
/// Конструктор. Создать безопасное подключение
/// </summary>
/// <param name="trader">Коннектор к торговой платформе</param>
public SafeConnection(BaseTrader trader)
{
Trader = trader;
}
/// <summary>
/// Вызвать событие появления нового исключения
/// </summary>
/// <param name="exception">Исключение</param>
protected virtual void OnNewException(Exception exception)
{
//Вызвать событие появления нового исключения
NewException(exception);
}
/// <summary>
/// Подключиться безопасно к торговой платформе
/// </summary>
public void _ConnectSafe()
{
//Интервал переподключения
Trader.ReConnectionSettings.Interval = TimeSpan.FromSeconds(10);
//Когда переподключаться
Trader.ReConnectionSettings.WorkingTime = ExchangeBoard.Forts.WorkingTime;
//Запускать ли заново экспрорт после переподключения
Trader.ReConnectionSettings.IsReStartExport = true;
//Подписаться на появление ошибки подключения от трейдера
Trader.ConnectionError += OnNewException;
//Подписаться на появление ошибок не выставленной заявки
Trader.OrdersRegisterFailed += fails => fails.ForEach(f => OnNewException(f.Error));
//Подписаться на событие успешного подключения к торговой платформе
Trader.Connected += () =>
{
try
{
//Запустить экспорт данных из торговой платформы
Trader.StartExport();
}
catch (Exception ex)
{
//Вызвать событие появления нового исключения
OnNewException(ex);
}
};
//Подключиться к торговой платформе
Trader.Connect();
}
public void ConnectSafe()
{
const string pathKey = (@"C:\Key_Junior\Key_Junior.txt");
var pathFile = File.ReadLines(pathKey).Skip(0).First();
var terminal = QuikTerminal.Get(pathFile);
if (!terminal.IsLaunched)
{
Console.WriteLine("Запускается Quik...");
terminal.Launch();
Console.WriteLine("Quik запущен");
}
if (!terminal.IsConnected)
{
var login = File.ReadLines(pathKey).Skip(1).First();
var password = File.ReadLines(pathKey).Skip(2).First();
terminal.Login(login, password);
Console.WriteLine("Авторизация произведена");
}
if (terminal.IsConnected) _ConnectSafe();
}
/// <summary>
/// Разорвать соединение с торговой платформой
/// </summary>
public void DisConnectSafe()
{
//Если коннектор к торговой платформе не пуст и соединение установлено
if (Trader != null)
{
if (Trader.IsConnected)
{
Trader.StopExport();
Trader.Disconnect();
}
Trader.Dispose();
// Trader = null;
GC.Collect();
}
}
/// <summary>
/// Возвращает. установлено ли соединение с торговй платформой
/// </summary>
public bool IsConnected
{
get
{
return Trader != null && Trader.IsConnected;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using Ecng.Xaml;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.TraderConnection;
namespace StockSharp.WpfConnectionInterface
{
/// <summary>
/// Логика взаимодействия для UserControl1.xaml
/// </summary>
public partial class InterFace : UserControl
{
//Поле, безопасный коннектор
private SafeConnection _safeConnection;
/// <summary>
/// Безопасный коннектор
/// </summary>
public SafeConnection SafeConnection
{
set
{
_safeConnection = value;
//Изменить доступность кнопки в соответствии с состоянием переменной _safeConnection
btnConnect.IsEnabled = _safeConnection!=null;
}
get { return _safeConnection; }
}
/// <summary>
/// Конструктор
/// </summary>
public InterFace()
{
InitializeComponent();
//Событие завершения загрузки данного контрола
Loaded += InterFace_Loaded;
//Сделать кнопку не доступной
btnConnect.IsEnabled = false;
}
/// <summary>
/// Событие завершения загрузки данного контрола
/// </summary>
/// <param name="sender"></param>
/// <param name="routedEventArgs"></param>
void InterFace_Loaded(object sender, RoutedEventArgs routedEventArgs)
{
//Получить родительское окно
var window = Window.GetWindow(Parent);
if (window != null)
window.Closed += delegate
{
if (_safeConnection != null)
_safeConnection.DisConnectSafe();
};
}
/// <summary>
/// Выбранный инструмент
/// </summary>
public Security SelectedSecurity
{
get { return (Security)cbSecurities.SelectedItem; }
}
/// <summary>
/// Выбранный портфель
/// </summary>
public Portfolio SelectedPortfolio
{
get { return (Portfolio)cbPortfolios.SelectedItem; }
}
/// <summary>
/// Нажатие на кнопку подключения
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ConnectClick(object sender, RoutedEventArgs e)
{
if (_safeConnection == null)
return;
if (_safeConnection.IsConnected)
{
btnConnect.Content = "Отключаем";
btnConnect.Background = System.Windows.Media.Brushes.OrangeRed;
cbPortfolios.Background = System.Windows.Media.Brushes.LightPink;
cbSecurities.Background = System.Windows.Media.Brushes.LightPink;
btnConnect.IsEnabled = false;
//Отписаться от события появления новых инструментов
_safeConnection.Trader.NewSecurities -= Trader_NewSecurities;
//Отписаться от события появления новых портфелей
_safeConnection.Trader.NewPortfolios -= Trader_NewPortfolios;
//Объявляем действие, которое нужно выполнить при отключении от торговой платформы
Action disconnected = null;
disconnected = () =>
{
_safeConnection.Trader.Disconnected -= disconnected;
this.GuiAsync(() =>
{
btnConnect.IsEnabled = true; btnConnect.Content = "Отключен";
});
};
_safeConnection.Trader.Disconnected += disconnected;
//Разорвать соединение
_safeConnection.DisConnectSafe();
}
else
{
btnConnect.Content = "Подключаем";
btnConnect.Background = System.Windows.Media.Brushes.LimeGreen;
if ( SelectedPortfolio != null) cbPortfolios.Background = System.Windows.Media.Brushes.LightGreen;
if ( SelectedSecurity != null) cbSecurities.Background = System.Windows.Media.Brushes.LightGreen;
btnConnect.IsEnabled = false;
//Подписаться на событие появления новых инструментов
_safeConnection.Trader.NewSecurities += Trader_NewSecurities;
//Подписаться на событие появления новых портфелей
_safeConnection.Trader.NewPortfolios += Trader_NewPortfolios;
//Объявляем действие, которое нужно выполнить при подключении к торговой платформе
Action connected = null;
connected = () =>
{
_safeConnection.Trader.Connected -= connected;
this.GuiAsync(() => { btnConnect.IsEnabled = true; btnConnect.Content = "Включен"; });
};
_safeConnection.Trader.Connected += connected;
//Подключиться безопасно
_safeConnection.ConnectSafe();
}
}
/// <summary>
/// Появление новых портфелей
/// </summary>
/// <param name="portfolios"></param>
private void Trader_NewPortfolios(IEnumerable<Portfolio> portfolios)
{
this.GuiAsync(() =>
{
cbPortfolios.ItemsSource = _safeConnection.Trader.Portfolios;
cbPortfolios.Background = System.Windows.Media.Brushes.LightGreen;
});
}
/// <summary>
/// Появление новых торговых инструментов
/// </summary>
/// <param name="securities"></param>
private void Trader_NewSecurities(IEnumerable<Security> securities)
{
this.GuiAsync(() =>
{
cbSecurities.ItemsSource = _safeConnection.Trader.Securities;
cbSecurities.Background = System.Windows.Media.Brushes.LightGreen;
});
}
public void PushInformationToStrategy(Strategy strategу)
{
strategу.Trader = SafeConnection.Trader;
strategу.Portfolio = SelectedPortfolio;
strategу.Security = SelectedSecurity;
}
private void cbSecurities_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
}
}