Questions about delegate and event handler

Questions about delegate and event handler

am 21.04.2008 03:44:35 von Fir5tSight

Hi,

I have a program that gets the prices of stocks in real-time. The
program consists of the following key components:


// Constructor
public GetRealTimeStockPrice()
{
// Step 1
foreach (IWatchList portfolio in
WatchListManager.GetPortfolios())
{
portfolio.OpenStocks(new
ListDataReadyDelegate(RegisterExistingStocks));

}


// Step 2
foreach (IWatchList portfolio in
WatchListManager.GetPortfolios())
{

portfolio.OpenStocks(new
ListDataReadyDelegate(OnStocksDownloaded));
}
}



void RegisterExistingStocks(IWatchList portfolio)
{
PriceForStock stockPrice;
string CurrentTicker;

foreach (IWatchEntry stock in portfolio.Stocks)
{
CurrentTicker = stock.Ticker;

if (!UniqueTickerRegistered(CurrentTicker))
{
stockPrice = new PriceForEntry(CurrentTicker);
mPriceCheckList.Add(stockPrice);
}
}
}



void OnStocksDownloaded(IWatchList portfolio)
{
string ticker;

foreach (IWatchEntry stock in portfolio.Stocks)
{
ticker = stock.Ticker;

if (!PriceObtained(ticker))
{
stock.SymbolData.Trade += new
TradeDelegate(SymbolData_Trade);
}
else // un-subscribe to the event once it's done
{
stock.SymbolData.Trade -= new
TradeDelegate(SymbolData_Trade);
}
}
}


Question 1:

I want to make sure that Step 1 happens before Step 2 in
"GetRealTimeStockPrice". Can anyone tell me if that is the case? (I
understand that with delegates, when it actually gets executed is out
of control.)


Question 2:

I was advised to use the structure below to get all of the existing
stocks in the porfolios:

foreach (IWatchList portfolio in
WatchListManager.GetPortfolios())
{
portfolio.OpenStocks(new
ListDataReadyDelegate(......));

}

Alternatively, I could use the following approach instead:

foreach (IWatchList portfolio in
WatchListManager.GetPortfolios())
{

foreach (IWatchEntry stock in portfolio.Stocks)
{
// blah blah blah

}

}

However, I was told by using "OpenStocks" with a delegate as its
parameter, it guarantees to get all of the stocks while the other
approach of looping through each stock may not work if the data for
the stock(s) are not immediately available.

Can anyone explain why using the delegate guarantees that the data are
available?


Question 3:

Is the way I un-subscribe to the "SymbolData_Trade" event correct?


if (!PriceObtained(ticker))
{
stock.SymbolData.Trade += new
TradeDelegate(SymbolData_Trade);
}
else // un-subscribe to the event once it's done
{
stock.SymbolData.Trade -= new
TradeDelegate(SymbolData_Trade);
}

I want to make sure that this removes the stock for which
"PriceObtained(ticker) == true" from the subscription. In other words,
once the price of a stock is obtained, it should be removed from the
watch list so that it won't react to the "SymbolData_Trade" event
anymore.

Would appreciate knowledgable people's advice!

Re: Questions about delegate and event handler

am 22.04.2008 11:10:03 von Nattydreadlock

On 21 apr, 03:44, Curious wrote:
> Hi,
>
> I have a program that gets the prices of stocks in real-time. The
> program consists of the following key components:
>
> =A0 =A0 =A0 =A0 // Constructor
> =A0 =A0 =A0 =A0 public GetRealTimeStockPrice()
> =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 // Step 1
> =A0 =A0 =A0 =A0 =A0 =A0 foreach (IWatchList portfolio in
> WatchListManager.GetPortfolios())
> =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 portfolio.OpenStocks(new
> ListDataReadyDelegate(RegisterExistingStocks));
>
> =A0 =A0 =A0 =A0 =A0 =A0 }
>
> =A0 =A0 =A0 =A0 =A0 =A0 // Step 2
> =A0 =A0 =A0 =A0 =A0 =A0 foreach (IWatchList portfolio in
> WatchListManager.GetPortfolios())
> =A0 =A0 =A0 =A0 =A0 =A0 {
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 portfolio.OpenStocks(new
> ListDataReadyDelegate(OnStocksDownloaded));
> =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 }
>
> =A0 =A0 =A0 =A0 void RegisterExistingStocks(IWatchList portfolio)
> =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 PriceForStock stockPrice;
> =A0 =A0 =A0 =A0 =A0 =A0 string CurrentTicker;
>
> =A0 =A0 =A0 =A0 =A0 =A0 foreach (IWatchEntry stock in portfolio.Stocks)
> =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CurrentTicker =3D stock.Ticker;
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!UniqueTickerRegistered(CurrentTicker)=
)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 stockPrice =3D new PriceForEntry(C=
urrentTicker);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mPriceCheckList.Add(stockPrice);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 }
>
> =A0 =A0 =A0 =A0void OnStocksDownloaded(IWatchList portfolio)
> =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 string ticker;
>
> =A0 =A0 =A0 =A0 =A0 =A0 foreach (IWatchEntry stock in portfolio.Stocks)
> =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ticker =3D stock.Ticker;
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!PriceObtained(ticker))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 stock.SymbolData.Trade +=3D new
> TradeDelegate(SymbolData_Trade);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else // un-subscribe to the event once it'=
s done
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 stock.SymbolData.Trade -=3D new
> TradeDelegate(SymbolData_Trade);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 }
>
> Question 1:
>
> I want to make sure that Step 1 happens before Step 2 in
> "GetRealTimeStockPrice". Can anyone tell me if that is the case? (I
> understand that with delegates, when it actually gets executed is out
> of control.)

You can't. I don't know how the code is written of your custom
classes, but with the information given here, I can't tell. You have
to make sure in your custom class that it doesn't invoke the second
delegate before the first.
>
> Question 2:
>
> I was advised to use the structure below to get all of the existing
> stocks in the porfolios:
>
> =A0 =A0 =A0 =A0 =A0 =A0 foreach (IWatchList portfolio in
> WatchListManager.GetPortfolios())
> =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 portfolio.OpenStocks(new
> ListDataReadyDelegate(......));
>
> =A0 =A0 =A0 =A0 =A0 =A0 }
>
> Alternatively, I could use the following approach instead:
>
> =A0 =A0 =A0 =A0 =A0 =A0 foreach (IWatchList portfolio in
> WatchListManager.GetPortfolios())
> =A0 =A0 =A0 =A0 =A0 =A0 {
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0foreach (IWatchEntry stock in portfolio=
..Stocks)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0// blah blah blah
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
>
> =A0 =A0 =A0 =A0 =A0 =A0 }
>
> However, I was told by using "OpenStocks" with a delegate as its
> parameter, it guarantees to get all of the stocks while the other
> approach of looping through each stock may not work if the data for
> the stock(s) are not immediately available.
>
> Can anyone explain why using the delegate guarantees that the data are
> available?
>
This is probably because in your custom class, the delegate is only
invoked when the data is available. Thus, when using the second you
immediatley invoke your method. Using the first you tell the portfolio
to invoke your method whenever the data is there.

> Question 3:
>
> Is the way I un-subscribe to the "SymbolData_Trade" event correct?
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!PriceObtained(ticker))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 stock.SymbolData.Trade +=3D new
> TradeDelegate(SymbolData_Trade);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else // un-subscribe to the event once it'=
s done
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 stock.SymbolData.Trade -=3D new
> TradeDelegate(SymbolData_Trade);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
>
> I want to make sure that this removes the stock for which
> "PriceObtained(ticker) == true" from the subscription. In other words,=

> once the price of a stock is obtained, it should be removed from the
> watch list so that it won't react to the "SymbolData_Trade" event
> anymore.
>
> Would appreciate knowledgable people's advice!

stock.SymbolData.Trade =3D null.

Re: Questions about delegate and event handler

am 23.04.2008 16:51:19 von Fir5tSight

Thanks for the input!

Re: Questions about delegate and event handler

am 23.04.2008 17:26:04 von Fir5tSight

Hi NattyDreadLock,

You're obviously knowledgable about delegates. May I get your input
about a threading issue?

I user System.Threading.Timer to check something every 15 seconds:

void OnTrade ()
{
// Check after the trade market first opens
if (!mIsTradeOpen)
{
mTimer = new Timer(new
TimerCallback(CheckHistoricalData), null, 15000, 15000);
mIsTradeOpen = true;

}
}

I have to use timer in the event handler "OnTrade" because the timer
only starts after there's a trading activity. However, it should not
start again when there's another trading activity - That's why I use a
global variable, "mIsTradeOpen", to make sure that the timer only
starts once.

Question 1: How can I find out how many instances of my timer is
running in my Task Manager? I want to make sure that there's only one
timer running.

Question 2: When shall I call mTimer.Dispose() to kill the timer? I'll
need to kill the timer after 5 PM when the trade market closes. But I
don't know where in my code I should kill the timer. Difficult
situation is that I start the timer in an event handler which is
initiated from the constructor.

Any input?