본문 바로가기
대충 만들면서 배우자/키워드검색

[C#/API]네이버 연관 검색어 프로그램 3(공통프로젝트(2):Extentions,QueueAsync Class)

by 프갭 2023. 3. 12.

네이버 API 및 11번가 Open API를 이용해 키워드 검색프로그램을 만들면서 개발의 방법 및 스킬을 늘리는게 목적입니다.

기본 베이스가 되는 프로그램 언어는 c#(WPF)로 진행 할 생각 입니다.

3) Extenstions.cs ,CommonUtils.cs

 

CommonUtils.cs
0.01MB

 

Extentions.cs
0.01MB

.

Extenstions 클래스는 확장 메서드 클래스 입니다

확장 메서드는 기존 클래스의 기능을 확장하는 메서드 입니다.

제 경우에는 자주 사용하는 기본 유틸성 기능을 확장 메서드로 사용하였습니다,

 

확정 메서드 생성 방법은

1) Static calss 생성

 

 

 

2)Static Method 생성

 

 

3)첫 번째 매개변수 (this 로확장 하고자 하는 객체를 지정)

4) 확장 메서드 사용시

확장 메서드의 네임스페이스 선언하면 확장 메서 노출 됩니다.

 

 

 

 

 

 

 

 

 

 

 

3) QueueAsync.cs 

비동기 클래스

비동기로 쓰레드를 분리 하고 싶을때 사용하는 클래스로

들어오는 메서드정보(QueueAsyncTask)를 큐에 담아 순차적으로 호출 하는 기능을 가지고 있습니다.

(선입선출_FIFO 자료구조)

 

동시에 여러 작업으로 나눠서 하고 싶을경우 GetInstance로 인스턴스를 분리하여 작업하면 됩니다.

 

EX)

1) 순차적으로 하나의 쓰레드로 작업 할경우

QueueAsync.Instance.AddTask(()=>{작업할 내용1 });

QueueAsync.Instance.AddTask(()=>{작업할 내용2 });

QueueAsync.Instance.AddTask(()=>{작업할 내용3 });

QueueAsync.Instance.AddTask(()=>{작업할 내용4 });

작업할 내용1 > 작업할 내용2 > 작업할 내용3 > 작업할 내용4 순으로 진행 됩니다.

 

1)  여러개의 쓰레드로 작업 할경우

QueueAsync.GetInstance(1).AddTask(()=>{작업할 내용1 });

QueueAsync.GetInstance(2).AddTask(()=>{작업할 내용2 });

QueueAsync.GetInstance(1).AddTask(()=>{작업할 내용3 });

QueueAsync.GetInstance(2).AddTask(()=>{작업할 내용4 });

1번 인스턴스 : 작업할 내용1 > 작업할 내용3

2번 인스턴스 : 작업할 내용2 > 작업할 내용4 

1번과 2번이 동시에 순차적으로 진행 됩니다.

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using EEH;

namespace EEH.Utils
{
    public class QueueAsync
    {
        private Queue<QueueAsyncTask> tasks = new Queue<QueueAsyncTask>();
        private QueueAsyncTask currentTask;
        private bool isStop = false;
        private BackgroundWorker worker;
        private static Dictionary<int, QueueAsync> instanceList = new Dictionary<int, QueueAsync>();
        private QueueAsync()
        {
            worker = new BackgroundWorker();
            worker.WorkerSupportsCancellation = true;
            worker.DoWork += (sender,e) => 
            {
                if (currentTask.ExNotNull() && currentTask.RunHandler.ExNotNull())
                {
                    currentTask.RunHandler();
                }
            };
            worker.RunWorkerCompleted += (sender, e) => 
            {
                if (currentTask.ExNotNull() && currentTask.CompleteHandler.ExNotNull())
                {
                    currentTask.CompleteHandler(!e.Error.ExNotNull(), e.Error);
                }


                currentTask = GetTask();
                if (currentTask.ExNotNull())
                {
                    worker.RunWorkerAsync();
                }
            };
        }

        public static QueueAsync Instance
        {
            get
            {
                return GetInstance(0);
            }
        }
        private static object instanceLock = "lock";
        public static QueueAsync GetInstance(int id)
        {
            lock (instanceLock)
            {
                if (!instanceList.ContainsKey(id))
                {
                    instanceList.Add(id, new QueueAsync());
                }
                return instanceList[id];
            }
        }

        public void AddTask(Action runHandler)
        {
            AddTask(runHandler,null); 
        }

        public void AddTask(Action runHandler, Action<bool, Exception> completeHandler)
        {
            QueueAsyncTask qTask = new QueueAsyncTask();
            qTask.RunHandler = runHandler;
            qTask.CompleteHandler = completeHandler;
            
            AddTask(qTask);
        }

        private object isLock = "lock";

        void AddTask(QueueAsyncTask task)
        {
            lock (isLock)
            {
                tasks.Enqueue(task);
                if (currentTask == null && !worker.IsBusy)
                {
                    currentTask = GetTask();
                    worker.RunWorkerAsync();
                }
            }
        }

        private QueueAsyncTask GetTask()
        {
            if (tasks.Count > 0 && !isStop)
            {
                return tasks.Dequeue();
            }

            return null;
        }

        public void Stop()
        {
            isStop = true;
            tasks.Clear();
            isStop = false;
        }
    }

    internal class QueueAsyncTask
    {
        public Action<bool ,Exception> CompleteHandler { get; set; }
        public Action RunHandler { get; set; }
    }
}

반응형

댓글