Providerクラスと継承元のDataProviderクラスを検証

今回は動作をテストしてみる。
検証用のコードは最後に。

検証用関数のcreateQP(string symbol)を呼んで
QuotesProviderのインスタンス生成と、それのイベント登録を行う
1) DataProvider.stateChanged
2) QuotesProvider.updated

QuotesProviderのfieldsにはlastとExchangeListedをセットしておく。とりあ。
createQPの引数であるsymbolを変えつつ、それぞれのハンドラ部分の結果をテスト。

まず、普通に
createQP("8798-TS");
印刷ログの結果は

```
----2019/03/17 21:01:07----
args.OldState.ToString() = loading
args.NewState.ToString() = loaded
sender.GetType().ToString() = tsdata.marketdata.QuotesProvider
objqp.Symbol = 8798
objqp.Quote["last"].doublevalue = 1714.00
initialupdate
objqp.Symbol = 8798
objqp.Quote["ExchangeListed"].stringValue = TSE

```
こうなる。

発火する順序は
1)DataProvider.stateChanged
2)QuotesProvider.updated
の順序で発火。

###DataProvider.stateChangedで取得できること
第二引数のtsdata.common.StateChangedEventArgs args によって
ステータスがloading から loadedに変わったことがわかる

また、第一引数senderで
発火元が tsdata.marketdata.QuotesProviderであること。
そして、発火元のsymbolプロパティが8798であることがわかる

最後に、ステータスがloadedであれば、senderを発火元のproviderにキャストすることで必要なQuotesプロパティを取得可能。

###QuotesProvider.updatedで取得できること
第二引数tsdata.marketdata.QuoteUpdatedEventArgs argsにて
updateイベントの発理由を取得できる　(InitialUpdate:1 , realtimeupdate:0)の2種類だ。

第一引数の扱いについてはDataProviderと変わらない。

###QuotesProvider.updateはDataProvider.stateChengedがloadedになってから発火する
存在しないsymbolデータでの取得テストではDataProviderstateChangeがfailedとなり、QuotesProvider.updatedは発火しない。

扱いの違いはこれだけ？と思う。
realtimeデータの受信がどうなるかわ今は日曜なので判別できないｓ・・


###検証用コード
```

using elsystem;
using elsystem.collections;
using tsdata.marketdata;
using tsdata.common;

var:Dictionary qpdic(null);	//生成したQuotesProviderを格納する入れ物


//デザイナージェネレーションコード :自動生成コード部（プログラムコピーしたときに忘れがちなのでじかに記述しておく
method override void InitializeComponent()
begin
		self.initialized += at_initialized;
		self.uninitialized += at_uninitialized;
end;
//デザイナージェネレーションコード END

method void AT_initialized( elsystem.Object sender, elsystem.InitializedEventArgs args ) 
begin

	qpdic = Dictionary.Create();

end;

method void AT_uninitialized( elsystem.Object sender, elsystem.UnInitializedEventArgs args ) 
begin
	clearprintlog();
end;

//与えられたsymbolごとにQuotesProviderインスタンスを生成
method void createQP(string strSymbol)
var: QuotesProvider qp ;
begin
	//初期値
	qp = null;
	try
		
		qp = new QuotesProvider;
		qp.Realtime = false;	//initialupdateのみでおｋなのでfalse
		qp.Symbol = strSymbol;
		qp.Fields = TokenList.create("ExchangeListed,last");
		
		qp.LoadProvider();
		{
		PriceDataStream オブジェクトがアップデートされると発生します。ハンドラーの args パラメーターが返すプロパティについては、「QuoteUpdatedEventArgs」を参照してください。
		}
		qp.Updated += self.QP_updated;
		qp.StateChanged += self.DataProvider_statechanged;
		
		qpdic.Add(strSymbol , qp);	//関数内ローカル変数であるQuotesProviderのインスタンスをDictionaryに入れてインスタンスを生存させる
		
	catch(elsystem.exception ex)
		print(strsymbol,ex.Message.ToString());
	end;
	
end;

//-----------------------------------------
//DataProviderのstatechangedイベントのハンドラ
//-----------------------------------------
method void DataProvider_statechanged( elsystem.Object sender, tsdata.common.StateChangedEventArgs args ) 
var:QuotesProvider objqp;
begin
	print(NewLine , "----" , datetime.now.ToString() , "----");
	print("args.OldState.ToString() = " , args.OldState.ToString());
	print("args.NewState.ToString() = " , args.NewState.ToString());	//tostring()必要
	print("sender.GetType().ToString() = " , sender.GetType().ToString());	//tsdata.marketdata.QuotesProvider
	
	objqp = sender astype QuotesProvider;
	print("objqp.Symbol = " , objqp.Symbol);
	if(args.NewState.ToString() = "loaded") then 
		print("objqp.Quote[",DoubleQuote,"last",DoubleQuote,"].doublevalue = " , objqp.Quote["last"].doublevalue);
	//stateがloadedになる前に呼び出すとエラー 
	//elsystem.InvalidOperationException:[プロバイダー]のデータは、オブジェクトが[ロード済み]になるまでアクセスできません。
end;


//-----------------------------------
//QuotesProviderのUPdatedイベントのはんどら
//-----------------------------------
method void QP_updated( elsystem.Object sender, tsdata.marketdata.QuoteUpdatedEventArgs args ) 
var:QuotesProvider objqp;
begin

	//updateイベントの発理由を取得できる　(InitialUpdate:1 , realtimeupdate:0)の2種類だ。
	print(args.Reason.ToString());
	
	//引数object senderをQuotesProviderにキャストすることで、QuotesProviderのデータを取得することができる。
	objqp = sender astype QuotesProvider;
	print("objqp.Symbol = " + objqp.Symbol);
	print("objqp.Quote[" + doubleQuote + "ExchangeListed" + doubleQuote + "].stringValue = " + objqp.Quote["ExchangeListed"].stringValue);
		

	//例えば、初回inisialUpdate時に閉じてしまえば、realtimeupdateの受信は発火しない（はず）
	//objqp.CloseProvider();
end;


method void test()
begin
	createQP("8798-TS");
	createQP("7203-TS");
	createQP("0000-TS");	//存在しないコード
	createQP("7048-TS");

end;

test();

```

###全テスト結果
```

----2019/03/17 21:18:36----
args.OldState.ToString() = loading
args.NewState.ToString() = loaded
sender.GetType().ToString() = tsdata.marketdata.QuotesProvider
objqp.Symbol = 8798-TS
objqp.Quote["last"].doublevalue = 1714.00
initialupdate
objqp.Symbol = 8798-TS
objqp.Quote["ExchangeListed"].stringValue = TSE

----2019/03/17 21:18:36----
args.OldState.ToString() = loading
args.NewState.ToString() = loaded
sender.GetType().ToString() = tsdata.marketdata.QuotesProvider
objqp.Symbol = 7203-TS
objqp.Quote["last"].doublevalue = 6615.00
initialupdate
objqp.Symbol = 7203-TS
objqp.Quote["ExchangeListed"].stringValue = TSE

----2019/03/17 21:18:36----
args.OldState.ToString() = loading
args.NewState.ToString() = loaded
sender.GetType().ToString() = tsdata.marketdata.QuotesProvider
objqp.Symbol = 7048-TS
objqp.Quote["last"].doublevalue = 1452.00
initialupdate
objqp.Symbol = 7048-TS
objqp.Quote["ExchangeListed"].stringValue = TSE

----2019/03/17 21:18:36----
args.OldState.ToString() = loading
args.NewState.ToString() = failed
sender.GetType().ToString() = tsdata.marketdata.QuotesProvider
objqp.Symbol = 0000-TS

```