diff --git a/MTApiService/ICommandManager.cs b/MTApiService/ICommandManager.cs
index 7f9d3eb2..2db3b80b 100755
--- a/MTApiService/ICommandManager.cs
+++ b/MTApiService/ICommandManager.cs
@@ -1,15 +1,8 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace MTApiService
+namespace MTApiService
{
public interface ICommandManager
{
- void EnqueueCommand(MtCommand command);
- MtCommand DequeueCommand();
-
- void OnCommandExecuted(MtExpert expert, MtCommand command, MtResponse response);
+ void EnqueueCommandTask(MtCommandTask task);
+ MtCommandTask DequeueCommandTask();
}
}
diff --git a/MTApiService/MTApiService.csproj b/MTApiService/MTApiService.csproj
index 7e85c90d..44777da8 100755
--- a/MTApiService/MTApiService.csproj
+++ b/MTApiService/MTApiService.csproj
@@ -59,6 +59,7 @@
+
diff --git a/MTApiService/MtCommandTask.cs b/MTApiService/MtCommandTask.cs
new file mode 100644
index 00000000..bf151e99
--- /dev/null
+++ b/MTApiService/MtCommandTask.cs
@@ -0,0 +1,37 @@
+using System.Threading;
+
+namespace MTApiService
+{
+ public class MtCommandTask
+ {
+ private readonly EventWaitHandle _responseWaiter = new AutoResetEvent(false);
+ private MtResponse _result;
+ private readonly object _locker = new object();
+
+ public MtCommandTask(MtCommand command)
+ {
+ Command = command;
+ }
+
+ public MtCommand Command { get; private set; }
+
+ public MtResponse WaitResult(int time)
+ {
+ _responseWaiter.WaitOne(time);
+ lock (_locker)
+ {
+ return _result;
+ }
+ }
+
+ public void SetResult(MtResponse result)
+ {
+ lock (_locker)
+ {
+ _result = result;
+ }
+ _responseWaiter.Set();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/MTApiService/MtExecutorManager.cs b/MTApiService/MtExecutorManager.cs
index 3e8d9f89..d73b0a2e 100755
--- a/MTApiService/MtExecutorManager.cs
+++ b/MTApiService/MtExecutorManager.cs
@@ -1,12 +1,9 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
namespace MTApiService
{
- class MtCommandExecutorManager : ICommandManager
+ internal class MtCommandExecutorManager : ICommandManager
{
#region Public Methods
@@ -14,8 +11,8 @@ namespace MTApiService
{
lock (_locker)
{
- mCommandExecutors.Clear();
- mCommands.Clear();
+ _commandExecutors.Clear();
+ _commandTasks.Clear();
}
}
@@ -24,26 +21,26 @@ namespace MTApiService
if (commandExecutor == null)
return;
+ var notify = false;
lock (_locker)
{
- if (mCommandExecutors.Contains(commandExecutor) == true)
+ if (_commandExecutors.Contains(commandExecutor))
return;
- mCommandExecutors.Add(commandExecutor);
-
- commandExecutor.CommandManager = this;
-
- if (mCurrentExecutor == null)
+ _commandExecutors.Add(commandExecutor);
+ if (_commandTasks.Count > 0)
{
- mCurrentExecutor = commandExecutor;
- mCurrentExecutor.IsCommandExecutor = true;
-
- if (mCommands.Count > 0)
- {
- mCurrentExecutor.NotifyCommandReady();
- }
+ notify = true;
}
}
+
+ commandExecutor.CommandExecuted += CommandExecutor_CommandExecuted;
+ commandExecutor.CommandManager = this;
+
+ if (notify)
+ {
+ NotifyCommandReady();
+ }
}
public void RemoveCommandExecutor(MtExpert commandExecutor)
@@ -51,80 +48,88 @@ namespace MTApiService
if (commandExecutor == null)
return;
+ var notify = false;
lock (_locker)
{
- if (mCommandExecutors.Contains(commandExecutor) == false)
+ if (_commandExecutors.Contains(commandExecutor) == false)
return;
- mCommandExecutors.Remove(commandExecutor);
-
- if (mCurrentExecutor == commandExecutor)
+ _commandExecutors.Remove(commandExecutor);
+ if (_commandTasks.Count > 0)
{
- mCurrentExecutor.IsCommandExecutor = false;
- mCurrentExecutor = mCommandExecutors.Count > 0 ? mCommandExecutors[0] : null;
-
- if (mCommands.Count > 0)
- {
- mCurrentExecutor.NotifyCommandReady();
- }
+ notify = true;
}
}
+
+ commandExecutor.CommandExecuted -= CommandExecutor_CommandExecuted;
+ commandExecutor.CommandManager = null;
+
+ if (notify)
+ {
+ NotifyCommandReady();
+ }
}
- public void EnqueueCommand(MtCommand command)
+ public void EnqueueCommandTask(MtCommandTask task)
{
- if (command == null)
+ if (task == null)
return;
lock (_locker)
{
- mCommands.Enqueue(command);
-
- mCurrentExecutor.NotifyCommandReady();
+ _commandTasks.Enqueue(task);
}
+
+ NotifyCommandReady();
}
- public MtCommand DequeueCommand()
+ public MtCommandTask DequeueCommandTask()
{
lock (_locker)
{
- return mCommands.Count > 0 ? mCommands.Dequeue() : null;
- }
- }
-
- public void OnCommandExecuted(MtExpert expert, MtCommand command, MtResponse response)
- {
- if (expert == null)
- return;
-
- if (CommandExecuted != null)
- {
- CommandExecuted(this, new MtCommandExecuteEventArgs(command, response));
- }
-
- lock (_locker)
- {
- if (expert == mCurrentExecutor)
- {
- if (mCommands.Count > 0)
- {
- mCurrentExecutor.NotifyCommandReady();
- }
- }
+ return _commandTasks.Count > 0 ? _commandTasks.Dequeue() : null;
}
}
#endregion
- #region Events
- public event EventHandler CommandExecuted;
+ #region Private Methods
+ private void NotifyCommandReady()
+ {
+ var commandExecutors = new List();
+ lock (_locker)
+ {
+ commandExecutors.AddRange(_commandExecutors);
+ }
+
+ foreach (var executor in commandExecutors)
+ {
+ executor.NotifyCommandReady();
+ }
+ }
+
+ private void CommandExecutor_CommandExecuted(object sender, EventArgs e)
+ {
+ var notify = false;
+ lock (_locker)
+ {
+ if (_commandTasks.Count > 0)
+ {
+ notify = true;
+ }
+ }
+
+ if (notify)
+ {
+ NotifyCommandReady();
+ }
+
+ }
#endregion
#region Private Fields
- private MtExpert mCurrentExecutor;
-
- private List mCommandExecutors = new List();
- private Queue mCommands = new Queue();
+ private readonly List _commandExecutors = new List();
+ private readonly Queue _commandTasks = new Queue();
private readonly object _locker = new object();
#endregion
diff --git a/MTApiService/MtExpert.cs b/MTApiService/MtExpert.cs
index dc03cb75..7ea328d8 100755
--- a/MTApiService/MtExpert.cs
+++ b/MTApiService/MtExpert.cs
@@ -1,7 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace MTApiService
{
@@ -10,43 +7,46 @@ namespace MTApiService
public delegate void MtQuoteHandler(MtExpert expert, MtQuote quote);
#region Properties
- private MtQuote _Quote;
+ private MtQuote _quote;
public MtQuote Quote
{
get
{
lock (_locker)
{
- return _Quote;
+ return _quote;
}
}
set
{
lock(_locker)
{
- _Quote = value;
+ _quote = value;
}
- if (QuoteChanged != null)
- {
- QuoteChanged(this, value);
- }
+ FireOnQuoteChanged(value);
}
}
+
public int Handle { get; private set; }
- private volatile bool _IsEnable = true;
+ private bool _isEnable = true;
public bool IsEnable
{
- get { return _IsEnable; }
- private set { _IsEnable = value; }
- }
-
- private volatile bool _IsCommandExecutor = true;
- public bool IsCommandExecutor
- {
- get { return _IsCommandExecutor; }
- set { _IsCommandExecutor = value; }
+ get
+ {
+ lock (_locker)
+ {
+ return _isEnable;
+ }
+ }
+ private set
+ {
+ lock (_locker)
+ {
+ _isEnable = value;
+ }
+ }
}
public ICommandManager CommandManager
@@ -55,14 +55,14 @@ namespace MTApiService
{
lock (_locker)
{
- return mCommandManager;
+ return _commandManager;
}
}
set
{
lock (_locker)
{
- mCommandManager = value;
+ _commandManager = value;
}
}
}
@@ -73,51 +73,43 @@ namespace MTApiService
{
Quote = quote;
Handle = handle;
- mMtHadler = mtHandler;
+ _mtHadler = mtHandler;
}
public void Deinit()
{
IsEnable = false;
-
- if (Deinited != null)
- {
- Deinited(this, EventArgs.Empty);
- }
+ FireOnDeinited();
}
public void SendResponse(MtResponse response)
{
- MtCommand command = mCommand;
- mCommand = null;
-
- ICommandManager commandManager = CommandManager;
- if (commandManager != null)
- {
- commandManager.OnCommandExecuted(this, command, response);
- }
+ _commandTask.SetResult(response);
+ _commandTask = null;
+ FireOnCommandExecuted();
}
public int GetCommandType()
{
- if (IsCommandExecutor)
+ var commandManager = CommandManager;
+ if (commandManager != null)
{
- ICommandManager commandManager = CommandManager;
- if (mCommandManager != null)
- {
- mCommand = mCommandManager.DequeueCommand();
- }
+ _commandTask = commandManager.DequeueCommandTask();
}
- return mCommand != null ? mCommand.CommandType : 0;
+ return _commandTask != null && _commandTask.Command != null ? _commandTask.Command.CommandType : 0;
}
public object GetCommandParameter(int index)
{
- if (mCommand != null && mCommand.Parameters != null
- && index >= 0 && index < mCommand.Parameters.Count)
+ if (_commandTask != null)
{
- return mCommand.Parameters[index];
+ var command = _commandTask.Command;
+ if (command != null && command.Parameters != null
+ && index >= 0 && index < command.Parameters.Count)
+ {
+ return command.Parameters[index];
+ }
}
return null;
@@ -131,13 +123,39 @@ namespace MTApiService
}
#endregion
-
#region Private Methods
private void SendTickToMetaTrader()
{
- if (mMtHadler != null)
+ if (_mtHadler != null)
{
- mMtHadler.SendTickToMetaTrader(Handle);
+ _mtHadler.SendTickToMetaTrader(Handle);
+ }
+ }
+
+ private void FireOnQuoteChanged(MtQuote quote)
+ {
+ var handler = QuoteChanged;
+ if (handler != null)
+ {
+ handler(this, quote);
+ }
+ }
+
+ private void FireOnDeinited()
+ {
+ var handler = Deinited;
+ if (handler != null)
+ {
+ handler(this, EventArgs.Empty);
+ }
+ }
+
+ private void FireOnCommandExecuted()
+ {
+ var handler = CommandExecuted;
+ if (handler != null)
+ {
+ handler(this, EventArgs.Empty);
}
}
#endregion
@@ -145,12 +163,13 @@ namespace MTApiService
#region Events
public event EventHandler Deinited;
public event MtQuoteHandler QuoteChanged;
+ public event EventHandler CommandExecuted;
#endregion
#region Private Fields
- private readonly IMetaTraderHandler mMtHadler;
- private MtCommand mCommand;
- private ICommandManager mCommandManager;
+ private readonly IMetaTraderHandler _mtHadler;
+ private MtCommandTask _commandTask;
+ private ICommandManager _commandManager;
private readonly object _locker = new object();
#endregion
}
diff --git a/MTApiService/MtServer.cs b/MTApiService/MtServer.cs
index 21c3a80f..6bef6ea9 100755
--- a/MTApiService/MtServer.cs
+++ b/MTApiService/MtServer.cs
@@ -1,18 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading;
using System.ServiceModel;
using System.Net;
using System.Diagnostics;
using System.ServiceModel.Channels;
-using System.Runtime.InteropServices;
using System.Net.Sockets;
namespace MTApiService
{
- class MtServer : IDisposable, IMtApiServer
+ internal class MtServer : IDisposable, IMtApiServer
{
#region Constants
private const int WAIT_RESPONSE_TIME = 40000; // 40 sec
@@ -23,12 +20,7 @@ namespace MTApiService
public MtServer(int port)
{
Port = port;
- mService = new MtService(this);
-
- mHosts = new List();
-
- mExecutorManager = new MtCommandExecutorManager();
- mExecutorManager.CommandExecuted += mExecutorManager_CommandExecuted;
+ _service = new MtService(this);
}
#endregion
@@ -39,21 +31,18 @@ namespace MTApiService
#region Public Methods
public void Start()
{
- bool hostsInitialized = InitHosts(Port);
+ var hostsInitialized = InitHosts(Port);
if (hostsInitialized == false)
- return;
-
- lock (mExpertsLocker)
{
- mExperts = new List();
+ Debug.WriteLine("Start: InitHosts failed. ");
}
}
private bool InitHosts(int port)
{
- lock (mHostLocker)
+ lock (_hosts)
{
- if (mHosts.Count > 0)
+ if (_hosts.Count > 0)
return false;
//init local pipe host
@@ -61,7 +50,7 @@ namespace MTApiService
ServiceHost localServiceHost = CreateServiceHost(localUrl, true);
if (localServiceHost != null)
{
- mHosts.Add(localServiceHost);
+ _hosts.Add(localServiceHost);
}
//init network hosts
@@ -79,7 +68,7 @@ namespace MTApiService
ServiceHost serviceHost = CreateServiceHost(networkUrl, false);
if (serviceHost != null)
{
- mHosts.Add(serviceHost);
+ _hosts.Add(serviceHost);
}
}
}
@@ -97,8 +86,8 @@ namespace MTApiService
{
try
{
- serviceHost = new ServiceHost(mService);
- Binding binding = CreateConnectionBinding(local);
+ serviceHost = new ServiceHost(_service);
+ var binding = CreateConnectionBinding(local);
serviceHost.AddServiceEndpoint(typeof(IMtApi), binding, serverUrlAdress);
serviceHost.Open();
@@ -116,17 +105,17 @@ namespace MTApiService
{
if (expert != null)
{
- expert.Deinited += new EventHandler(expert_Deinited);
- expert.QuoteChanged += new MtExpert.MtQuoteHandler(expert_QuoteChanged);
+ expert.Deinited += expert_Deinited;
+ expert.QuoteChanged += expert_QuoteChanged;
- lock (mExpertsLocker)
+ lock (_experts)
{
- mExperts.Add(expert);
+ _experts.Add(expert);
}
- mExecutorManager.AddCommandExecutor(expert);
+ _executorManager.AddCommandExecutor(expert);
- mService.OnQuoteAdded(expert.Quote);
+ _service.OnQuoteAdded(expert.Quote);
}
}
@@ -140,31 +129,11 @@ namespace MTApiService
if (command != null)
{
- EventWaitHandle responseWaiter = new AutoResetEvent(false);
-
- lock (mResponseLocker)
- {
- mResponseWaiters[command] = responseWaiter;
- }
-
- mExecutorManager.EnqueueCommand(command);
+ var task = new MtCommandTask(command);
+ _executorManager.EnqueueCommandTask(task);
//wait for execute command in MetaTrader
- responseWaiter.WaitOne(WAIT_RESPONSE_TIME);
-
- lock (mResponseLocker)
- {
- if (mResponseWaiters.ContainsKey(command) == true)
- {
- mResponseWaiters.Remove(command);
- }
-
- if (mResponses.ContainsKey(command) == true)
- {
- response = mResponses[command];
- mResponses.Remove(command);
- }
- }
+ response = task.WaitResult(WAIT_RESPONSE_TIME);
}
return response;
@@ -172,9 +141,9 @@ namespace MTApiService
public IEnumerable GetQuotes()
{
- lock (mExpertsLocker)
+ lock (_experts)
{
- return (from s in mExperts select s.Quote);
+ return (from s in _experts select s.Quote);
}
}
@@ -183,23 +152,26 @@ namespace MTApiService
#region Private Methods
private void stopTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
- int expertsCount = 0;
+ var expertsCount = 0;
- lock (mExpertsLocker)
+ lock (_experts)
{
- expertsCount = mExperts.Count();
+ expertsCount = _experts.Count();
}
if (expertsCount == 0)
{
- mService.OnStopServer();
+ _service.OnStopServer();
- stop();
+ Stop();
}
var stopTimer = sender as System.Timers.Timer;
- stopTimer.Stop();
- stopTimer.Elapsed -= stopTimer_Elapsed;
+ if (stopTimer != null)
+ {
+ stopTimer.Stop();
+ stopTimer.Elapsed -= stopTimer_Elapsed;
+ }
}
private string CreateConnectionAddress(string host, int port, bool local)
@@ -265,65 +237,62 @@ namespace MTApiService
return connectionBinding;
}
- private void stop()
+ private void Stop()
{
- mExecutorManager.Stop();
+ _executorManager.Stop();
- lock (mHostLocker)
+ lock (_hosts)
{
- if (mHosts.Count == 0)
+ if (_hosts.Count == 0)
return;
try
{
- foreach (var host in mHosts)
+ foreach (var host in _hosts)
{
host.Close();
}
}
catch (TimeoutException)
{
- foreach (var host in mHosts)
+ foreach (var host in _hosts)
{
host.Abort();
}
}
catch (Exception)
{
+ // ignored
}
finally
{
- mHosts.Clear();
+ _hosts.Clear();
}
}
- if (Stopped != null)
- {
- Stopped(this, EventArgs.Empty);
- }
+ FireOnStopped();
}
private void expert_Deinited(object sender, EventArgs e)
{
- MtExpert expert = (MtExpert)sender;
- int expertsCount = 0;
+ if (sender == null)
+ return;
- lock (mExpertsLocker)
+ var expert = (MtExpert)sender;
+ var expertsCount = 0;
+
+ lock (_experts)
{
- mExperts.Remove(expert);
-
- expertsCount = mExperts.Count();
+ _experts.Remove(expert);
+ expertsCount = _experts.Count();
}
- mExecutorManager.RemoveCommandExecutor(expert);
+ _executorManager.RemoveCommandExecutor(expert);
- if (expert != null)
- {
- expert.Deinited -= expert_Deinited;
- expert.QuoteChanged -= expert_QuoteChanged;
+ expert.Deinited -= expert_Deinited;
+ expert.QuoteChanged -= expert_QuoteChanged;
- mService.OnQuoteRemoved(expert.Quote);
- }
+ _service.OnQuoteRemoved(expert.Quote);
if (expertsCount == 0)
{
@@ -334,28 +303,18 @@ namespace MTApiService
}
}
- void mExecutorManager_CommandExecuted(object sender, MtCommandExecuteEventArgs e)
- {
- EventWaitHandle responseWaiter = null;
-
- lock (mResponseLocker)
- {
- if (mResponseWaiters.ContainsKey(e.Command) == true)
- {
- responseWaiter = mResponseWaiters[e.Command];
- mResponses[e.Command] = e.Response;
- }
- }
-
- if (responseWaiter != null)
- {
- responseWaiter.Set();
- }
- }
-
private void expert_QuoteChanged(MtExpert expert, MtQuote quote)
{
- mService.QuoteUpdate(quote);
+ _service.QuoteUpdate(quote);
+ }
+
+ private void FireOnStopped()
+ {
+ var handler = Stopped;
+ if (handler != null)
+ {
+ handler(this, EventArgs.Empty);
+ }
}
#endregion
@@ -367,25 +326,16 @@ namespace MTApiService
#region IDispose
public void Dispose()
{
- stop();
+ Stop();
}
#endregion
#region Fields
- private readonly MtService mService;
- private readonly List mHosts;
-
- private readonly MtCommandExecutorManager mExecutorManager;
- private List mExperts;
-
- private readonly Dictionary mResponseWaiters = new Dictionary();
- private readonly Dictionary mResponses = new Dictionary();
-
- private readonly object mResponseLocker = new object();
- private readonly object mHostLocker = new object();
- private readonly object mExpertsLocker = new object();
- private readonly object mCommandExecutorsLocker = new object();
+ private readonly MtService _service;
+ private readonly List _hosts = new List();
+ private readonly MtCommandExecutorManager _executorManager = new MtCommandExecutorManager();
+ private readonly List _experts = new List();
#endregion
}
}
diff --git a/mq4/Trend.zip b/mq4/Trend.zip
deleted file mode 100755
index 12b150fb..00000000
Binary files a/mq4/Trend.zip and /dev/null differ