#region ImageToBytes

        /// <summary>

        /// 이미지를 바이트 배열로 변환합니다.

        /// </summary>

        /// <param name="image">변환할 이미지입니다.</param>

        /// <returns>바이트배열입니다.</returns>

        byte[] ImageToBytes(Image image)

        {

            // 이미지 포멧을 가져옵니다.

            ImageFormat imageFormat = image.RawFormat;

            using (MemoryStream memoryStream = new MemoryStream())

            {

                // 이미지 포멧에 따라 스트림에 이미지를 저장합니다.

                if (imageFormat.Equals(ImageFormat.Jpeg))

                {

                    image.Save(memoryStream, ImageFormat.Jpeg);

                }

                else if (imageFormat.Equals(ImageFormat.Png))

                {

                    image.Save(memoryStream, ImageFormat.Png);

                }

                else if (imageFormat.Equals(ImageFormat.Bmp))

                {

                    image.Save(memoryStream, ImageFormat.Bmp);

                }

                else if (imageFormat.Equals(ImageFormat.Gif))

                {

                    image.Save(memoryStream, ImageFormat.Gif);

                }

                else if (imageFormat.Equals(ImageFormat.Icon))

                {

                    image.Save(memoryStream, ImageFormat.Icon);

                }

 

                // 배열을 선언합니다.

                byte[] buffer = new byte[memoryStream.Length];

 

                // 배열을 체웁니다.

                memoryStream.Seek(0, SeekOrigin.Begin);

                memoryStream.Read(buffer, 0, buffer.Length);

 

                return buffer;

            }

        }

        #endregion

 

* 빗썸 코인정보 Class

    public class CoinInfo

    {

        public string CoinType       { get; set; }

        public DateTime CoinTime     { get; set; }

        public string Status         { get; set; }

        public int OpeningPrice     { get; set; }

        public int ClosingPrice     { get; set; }

        public int MinPrice         { get; set; }

        public int MaxPrice         { get; set; }

        public string AveragePrice { get; set; }

        public string UnitsTraded   { get; set; }

        public string Volume1Day    { get; set; }

        public string Volume7Day    { get; set; }

        public int BuyPrice         { get; set; }

        public int SellPrice        { get; set; }

        public string Date           { get; set; }

    }

 

* 빗썸 데이터 가져오기

 

                //string page = "https://api.bithumb.com/public/ticker/BTC"; // 특정 화폐정보만 가져올때

                string page = "https://api.bithumb.com/public/ticker/ALL";

                HttpClient client = new HttpClient();

                var response = await client.GetAsync(page);

                if (!response.IsSuccessStatusCode) return;

 

                using (HttpContent content = response.Content)

                {

                    string result = await content.ReadAsStringAsync();

                    var o = JsonConvert.DeserializeObject(result);

                    JObject JObj = JObject.Parse(result);

 

                    //BTC,ETH,DASH,LTC,ETC,XRP,BCH,XMR,ZEC,QTUM,BTG,EOS

                    string[] coinTypes = "BTC,ETH,DASH,LTC,ETC,XRP,BCH,XMR,ZEC,QTUM,BTG,EOS".Split(',');

 

                    string status = JObj["status"].ToString();

                    if (status != "0000") return;

 

                    string date = JObj["data"]["date"].ToString();

 

                    // 데이터 가져온 시간입니다.

                    DateTime coinTime = DateTime.Now;

                    List<CoinInfo> coinInfoList = new List<CoinInfo>();

 

                    foreach (string coinType in coinTypes)

                    {

                        CoinInfo coinInfo = new CoinInfo() { CoinType = coinType, Status = status, Date = date, CoinTime = coinTime };

 

                        coinInfo.OpeningPrice = int.Parse(JObj["data"][coinType]["opening_price"].ToString());

                        coinInfo.ClosingPrice = int.Parse(JObj["data"][coinType]["closing_price"].ToString());

                        coinInfo.MinPrice = int.Parse(JObj["data"][coinType]["min_price"].ToString());

                        coinInfo.MaxPrice = int.Parse(JObj["data"][coinType]["max_price"].ToString());

                        coinInfo.AveragePrice = JObj["data"][coinType]["average_price"].ToString();

                        coinInfo.UnitsTraded = JObj["data"][coinType]["units_traded"].ToString();

                        coinInfo.Volume1Day = JObj["data"][coinType]["volume_1day"].ToString();

                        coinInfo.Volume7Day = JObj["data"][coinType]["volume_7day"].ToString();

                        coinInfo.BuyPrice = int.Parse(JObj["data"][coinType]["buy_price"].ToString());

                        coinInfo.SellPrice = int.Parse(JObj["data"][coinType]["sell_price"].ToString());

 

                        coinInfoList.Add(coinInfo);

                    }

                }

 

* 빗썸 예시 데이터 (Json) - 2019-05-21 오후10:45 데이터

사용자 컨트롤 작성시 사용자 컨트롤에 다른 컨트롤들을

배치 시킬수 있도록 하기 위한 방법입니다.

 

UserControl (TestControl) 을 만들고 사용자가 편집 가능하게 할 컨트롤을 아래 처럼 정의합니다.

 

namespace Test

{

    public partial class TestControl : UserControl

    {

        /// <summary>

        /// 사용자 정의 판넬입니다.

        /// </summary>

        [Category("Test")]

        [Browsable(false)]

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

        public Panel UserPanel => this.userPanel;

    }

}

 

ParentControlDesigner 를 상속받는 디자이너 클래스를 추가합니다.

 

using System.ComponentModel;

using System.Windows.Forms.Design;

 

namespace Test

{

   public class TestControlDesigner : ParentControlDesigner

    {

        public override void Initialize(IComponent component)

        {

            base.Initialize(component);

 

            TestControl testControl = component as TestControl;

            if (dsGridSelector != null)

            {

                base.EnableDesignMode(dsGridSelector.UserPanel, "UserPanel");

            }

        }

    }

}

 

UserControl 의 상단에 아래 처럼 처리합니다.

 

namespace Test

{

    [Designer(typeof(TestControlDesigner))]

    public partial class TestControl : UserControl

    {

        /// <summary>

        /// 사용자 정의 판넬입니다.

        /// </summary>

        [Category("Test")]

        [Browsable(false)]

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

        public Panel UserPanel => this.userPanel;

    }

}

 

이게 디자이너 단에서 UserPanel 부분으로 다른 컨트롤 들을 배치 시킬수 있습니다.

 

만약 Panel 안의 Panel 을 처리하고 싶을때는 부모 판넬도 위와 같은 처리를 해야

정상적으로 동작합니다.

 

예시)

Panel1 안에 Panel2 가 있는 경우 Panel2 로 디자이너에서 편집이 가능하게 할 경우

 

namespace Test

{

    [Designer(typeof(TestControlDesigner))]

    public partial class TestControl : UserControl

    {

        /// <summary>

        /// 사용자 정의 판넬1입니다.

        /// </summary>

        [Category("Test")]

        [Browsable(false)]

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

        public Panel UserPanel1 => this.userPanel1;

 

        /// <summary>

        /// 사용자 정의 판넬2입니다.

        /// </summary>

        [Category("Test")]

        [Browsable(false)]

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

        public Panel UserPanel2 => this.userPanel2;

 

    }

}

 

 

using System.ComponentModel;

using System.Windows.Forms.Design;

namespace Test

{

    public class TestControlDesigner : ParentControlDesigner

    {

        public override void Initialize(IComponent component)

        {

            base.Initialize(component);

 

            TestControl testControl = component as TestControl;

            if (dsGridSelector != null)

            {

                base.EnableDesignMode(dsGridSelector.UserPanel1, "UserPanel1");

                base.EnableDesignMode(dsGridSelector.UserPanel2, "UserPanel2");

            }

        }

    }

}

 

 

 

 

 

 

Task.WaitAll(t1,t2);
Parallel.Invoke(()=>{work(1,2)}
목(mock) : 대리인 역할을 하는 객체
Linq 의 sort 는 원래 데이터를 제거 하고 orderby 는 원래 데이터를 유지한다.
Cast 는 예외를 발생 시킨다.- 단순히 형을 반환한다.
OfType 는 예외를 발생 시키지 않는다. - 형변환은 물론 형에 일치하는 데이터를 추출한다.

https://csharp.hotexamples.com/examples/System.Drawing/Image/Save/php-image-save-method-examples.html

결론.

const 컴파일 상수는 성능이 매우 중요하고 상수의 값이 절대로 바뀌지 않는 경우만 제한적으로 사용하는 것이 좋다.

 

readonly 런타임 상수는..

- const 에 비해 느리지만 유연성이 좋다.

- 어떤 타입과도 함께 사용할수 있다.

- 메서드내에서는 선언할 수 없다.

- 클래스별로 서로 다른 값을 가질 수 있다.

- 값을 변경 한 경우 리빌드 하지 않아도 런타임시 값을 참조하기 때문에 어샘블리만 리빌드 되어있으면 변경된 값을 가져올수 있다.

* 런타임에 값이 평가되어 값을 가지지 않고 상수에 대한 참조 컴파일 된다.

* 맴버 초기화 구문뿐 아니라 생성자를 통해서도 초기화 가능하다.

 

const 컴파일 타임 상수는..

- 속도가 빠르고 변경이 불가능하다.

- 내장자료형(primitive types)과 enums,string으로만 사용할 수 있다.

- const. 컴파일 타임 상수는 메서드내에서 정의될 수 있다.

- 하나의 값만 가질 수 있다.

- 값을 변경 한 경우 리빌드 해야함 참조한 프로젝트에서 변경된 값을 가져올수 있다.

 

1. 지역변수를 선언할 때는 var 를 사용하는 것이 낫다.

정확한 반환 타입을 알면 상관없지만 어설프게 정확한 반환타입을 알지 못한채 명시적 타입을 쓰게되면

득보다 실이 많다.

변수의 타입보다는 변수의 의미파악에 더 집중할 수 있게 한다.

가독성과 자동타입변환 과정으로 인해 버그를 만들수도 있지만

var 변수로 인해 가독성이 방해되는 코드라면 대부분

명시적으로 써도 가독성은 불편한건 마찬가지이다.

c# 8 에서 부터 지원되는 문법으로 아래처럼 사용할 수 있다.

int[] arr = { 1, 2, 3, 4 };
var lastIndex = new Index(1, true);
int lastNum = arr[lastIndex]; // 4
lastNum = arr[^1]; // 위 코드와 동일
nt[] arr = { 1, 2, 3, 4 };
Range range = 1..^1;
var sub = arr[range]; // [2, 3]
sub = arr[1..^1]; // 위 코드와 동일
var sub2 = arr[1..]; // [2, 3, 4]
var sub3 = arr[..3]; // [1, 2, 3]
var sub4 = arr[..]; // [1, 2, 3, 4]
string s = "Hello, World!"[..^8]; // "Hello"

 

파이썬과 동일하게.. 이건머.. 하는 짓? 이지?;;;

 

MissingMethod 에러가 발생되었다. 아래 에러와 같이..

!!0[] System.Array.Empty()

 

로컬에서 빌드한 dll 을 서버 pc 에 적용했는데 해당에러가 계속 발생되었다.

그래서 다른 메서드를 추가해 봤다 (인자가 없는) 그런데 그메서드는 잘 호출이 되었다.

아 이건 머지 하다가 혹시나해서 인자가 있는 메서드를 만들어 호출하니

위와 같은 에러가 발생되었다..

결론은 서버에 빌드한 dll 의 .NET 버전이 설치되어있지 않아서였다.

서버에 .NET 버전을 설치하던지 아니면 dll 빌드시 서버의 .NET 버전에 맞춰

빌드해야한다.

 

아래 링크는 서버의 .NET 버전을 확인하는 방법이다.

https://docs.microsoft.com/ko-kr/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed

콘솔앱을 하나 만듭니다.

만들어진 상태에서 해당 프로젝트의 메뉴에서 추가>컨테이너 오케스트레이터 지원 을 클릭합니다.

아래처럼 Docker Compose 를 선택하고

윈도우서버로 서버가 동작중이므로  Windows 를 선택했습니다.

 

아래처럼 Docker-compose 프로젝트가 추가됩니다.

yml 파일을 이용해 먼가 더 추가적이 설정이 가능한데 이는 다음에 더 자세히

살펴봐야겠습니다.

F5 로 실행해보면 아래 처럼

제가 만든 콘솔엡의 이미지가 생성된걸 불수 있습니다. (근데 사이즈가 왜저렇게 크지..;;)

(Docker image 명령어를 파워쉘에서 실행)

아래처럼 중단을 걸면 디버깅도 가능합니다.

 

소스파일

DockerConsoleApp.zip

 

'C#' 카테고리의 다른 글

Index, Range, hat('^')  (0) 2019.02.22
!!0[] System.Array.Empty() 에러  (0) 2019.01.17
Visual Studio 에서 Docker 로 디버깅하기 - 콘솔앱  (0) 2018.11.04
compile c# online  (0) 2018.10.01
[C#)네이버 카페 API 이용하여 사진 포함 글 등록하기  (0) 2018.09.26
[C#]TensorCamera  (0) 2018.09.01

+ Recent posts