일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- c# maui
- upbit
- c# 업비트 api키 목록
- Prism
- c# api호출
- 차트
- c# websocket
- 업비트 차트
- Upbit API
- c# restapi 호출
- 즐겨찾기
- C#
- 북마크
- c# 차트
- maui
- WPF
- Chart
- c# 라이브 차트
- 업비트 API
- 라이브 차트
- 업비트 c#
- c# 업비트
- 나만의 사이트모음집
- XAML
- c# restapi
- 업비트
- Today
- Total
하아찡
C# 업비트 캔들 작업 이슈 본문
캔들작업하는데 이슈가 발생.
예상 이슈는 Context Switch 발생같음(멀티쓰레드를 사용하게되면 발생하는 문제).
예를 들어 웹소켓을 통해 Trade 데이터를 실시간으로 받아와서 해당 데이터를 각각의 View 및 Page에게 전달해주기위해 이벤트를 발생시키는데, 한번에 동시 다발적인 처리를 동시 다발적으로 처리해서 그렇다...? 말이 이상하긴한데 C++ 게임 서버 공부할때 지겹게 본 과정이기에 해결하기위해 JobQueue와 같은 방식을 사용해서 처리해야 될듯합니다.
일단 JobQueue와 같은 방식으로 처리하기 전에 동시다발적인 처리를 동시다발적인 처리를 했다라는 아리달쏭한 말을 한번 보시죠.
해당 그림을 보시면 각각의 이벤트가 동일한 ChartData를 참조하여 로직을 처리합니다.
그래서 캔들을 추가하는 로직이 발생했을때 각종 이벤트가 동일한 ChartData값을 참조하여 로직을 처리하다보니 각각 이벤트마다 캔들생성 로직을 처리하게돼서 아래와 같은 현상이 발생하게 됩니다.
else if (NowTradeTime > ChartLastTime)
{
MainThread.BeginInvokeOnMainThread(() =>
{
// TODO 내가가진 분봉보다 미래값
Candle nowCandle = new Candle();
nowCandle.Timestamp = coin.ttms; // 마지막으로 체결된 타임스탬프
nowCandle.Tp = coin.tp; // 현재가
nowCandle.Op = coin.tp; // 시가
nowCandle.Lp = coin.tp; // 저가
nowCandle.Hp = coin.tp; // 고가
nowCandle.Utc = coin.td + " " + coin.ttm;
ChartData.Add(nowCandle);
ChartView.Add(nowCandle);
});
}
해당 이벤트가 발생했을때 현재차트에 있는 시간과 받은데이터의 시간이 다를경우 캔들을 생성하는데 각각의 이벤트가 캔들을 생성해서 위 이미지와같은 현상이 발생.
그래서 C++게임서버에서 .JobQueue를 사용해서 하나의 쓰레드에서 처리를 하게 하는 방식을 가져옵니다.
일단 이미지로 보시면
이벤트 발생하면 Queue에다 순서대로 넣어서 순차적으로 실행하게되면 위와같은 중복 캔들이 사라질겁니다.
그래서 저는 따로 쓰레드를 생성하지않고 그냥 타이머를 통해서 사용했습니다. 특정시간마다 Queue에 있는 내용을 꺼내서 처리합니다.
private readonly System.Timers.Timer _tradeTimer = new(10); // 10ms
private readonly ConcurrentQueue<Trade> _tradeQueue = new(); // JobQueue
private void StartTradeProcessor()
{
_tradeTimer.Elapsed += OnTradeTimerElapsed;
_tradeTimer.AutoReset = true;
_tradeTimer.Start();
}
private void OnTradeTimerElapsed(object sender, ElapsedEventArgs e)
{
MainThread.BeginInvokeOnMainThread(() =>
{
while (_tradeQueue.TryDequeue(out var trade))
{
var nowData = ChartData[ChartData.Count - 1];
DateTime ChartLastTime = DateTime.Parse(nowData.Utc); // 차트 마지막시간
DateTime NowTradeTime = DateTime.Parse(trade.td + " " + trade.ttm); // 체결시간
DateTime chartTrimmed = new DateTime(ChartLastTime.Year, ChartLastTime.Month, ChartLastTime.Day, ChartLastTime.Hour, ChartLastTime.Minute, 0);
DateTime nowTrimmed = new DateTime(NowTradeTime.Year, NowTradeTime.Month, NowTradeTime.Day, NowTradeTime.Hour, NowTradeTime.Minute, 0);
Candle nowCandle = new Candle();
nowCandle.Timestamp = trade.ttms; // 마지막으로 체결된 타임스탬프
nowCandle.Tp = trade.tp; // 현재가
nowCandle.Op = trade.tp; // 시가
nowCandle.Lp = trade.tp; // 저가
nowCandle.Hp = trade.tp; // 고가
nowCandle.Utc = trade.td + " " + trade.ttm;
if (NowTradeTime > ChartLastTime)
{
ChartData.Add(nowCandle);
ChartView.Add(nowCandle);
}
}
});
}
ConcurrentQueue 가 내부적으로 Lock-Free를 해줘서 사용했습니다.
그 결과
시간이 겹치는 문제 해결.
'C# > 업비트' 카테고리의 다른 글
C# MAUI 차트 - 휠 (0) | 2025.05.27 |
---|---|
C# 업비트 차트 라이브 처리 (0) | 2025.05.26 |
C# 업비트 API 캔들데이터처리 (0) | 2025.05.22 |
C# 업비트API 요청수 제한 (1) | 2025.05.22 |
C# 업비트 APIKey 인증 (0) | 2025.05.21 |