개발꿈나무
8/12(목) 4일차 C#.Net 교육 본문
C# Lab
SharpLab
Code [connection lost, reconnecting…]
sharplab.io
data => primitive(integer: calculation) / non-primitive(string/struct/class/record)
- Primitive(mutable): 계산 가능한 변수 (ex. integer)
- Non-Primitive(immutable): 계산 불가능한 변수 (ex.string)
Type: ValueType(primitive) / Reference(non-primitive)
-----
Immutable object
string strS = "Hello, World!"; // S: group object라는 의미
char ch = strS[0]; // 왼쪽으로 못 오는 것: immutable (ex) strS[0] = 'AAA' -> ERROR
for (int i = 0; i < strS.Length; i++)
{
WriteLine($"REPL strS[{i}..]: {strS[i..]} strS[..^{i}]: {strS[..^i]} ch: {ch} strS[{i}]: {strS[i]}"); //[i..]: i가 시작점
}
<result>
REPL strS[0..]: Hello, World! strS[..^0]: Hello, World! ch: H strS[0]: H
REPL strS[1..]: ello, World! strS[..^1]: Hello, World ch: H strS[1]: e
REPL strS[2..]: llo, World! strS[..^2]: Hello, Worl ch: H strS[2]: l
REPL strS[3..]: lo, World! strS[..^3]: Hello, Wor ch: H strS[3]: l
REPL strS[4..]: o, World! strS[..^4]: Hello, Wo ch: H strS[4]: o
REPL strS[5..]: , World! strS[..^5]: Hello, W ch: H strS[5]: ,
REPL strS[6..]: World! strS[..^6]: Hello, ch: H strS[6]:
REPL strS[7..]: World! strS[..^7]: Hello, ch: H strS[7]: W
REPL strS[8..]: orld! strS[..^8]: Hello ch: H strS[8]: o
REPL strS[9..]: rld! strS[..^9]: Hell ch: H strS[9]: r
REPL strS[10..]: ld! strS[..^10]: Hel ch: H strS[10]: l
REPL strS[11..]: d! strS[..^11]: He ch: H strS[11]: d
REPL strS[12..]: ! strS[..^12]: H ch: H strS[12]: !
-----
string strS = "Hello, World!"; // S: group object라는 의미
// Collection service
foreach (var kkk in strS) Write($" {kkk}");
WriteLine();
//Interpace operation: IoC(class + class relationship)
IEnumerator ptr = strS.GetEnumerator();
while (ptr.MoveNext()) Write($" {ptr.Current}"); //dynamic coding
// mutable operation
//set과 init의 차이: set은 처음 정의할 때 한번만 물려주지만 init은 호출할 때마다 물려줌(다른 객체로??)
public partial class HeleleClass //code-first에서 model이라고 함
{
// property
public int Suja { get; init; } = default(int);
}
// -> immutable operation
public partial record HeleleRecord
{
// property
public int Suja { get; init; } = default(int);
}
public partial record class HeleleRecord1
{
// property
public int Suja { get; init; } = default(int);
}
public partial record struct HeleleRecord2
{
// property
public int Suja { get; init; } = default(int);
}
-----
Mutable VS Immutable
List (mutable VS immutable)
string strS = "Hello, World!"; // S: group object라는 의미
List<int> lists = new() { 1, 2, 3, 4 }; //mutable operation
// lists = new() { 5, 6, 7, 8 }; ERROR 나지 않음
IReadOnlyList<int> listss = lists.ToImmutableList(); //imutable operation, duality = Isomorphic(동형사상)
// listss = new() { 5, 6, 7, 8 }; ERROR 발생
//Interpace operation: IoC(class + class relationship)
IEnumerator ptr = strS.GetEnumerator();
while (ptr.MoveNext())
{
Write($" {ptr.Current}");
}//dynamic coding
WriteLine();
ptr = lists.GetEnumerator();
while (ptr.MoveNext())
{
Write($" {ptr.Current}");
}
WriteLine();
ptr = listss.GetEnumerator();
while (ptr.MoveNext())
{
Write($" {ptr.Current}");
}
WriteLine();
Dictionary (mutable VS immutable)
// mutable Dictionary
Dictionary<int, string> dics = new()
{
{ 1, "aaa"},
{ 2, "bbb"},
{ 3, "ccc"},
};
dics = new()
{
[1] = "aaaa",
[2] = "bbbb",
[3] = "cccc",
}; //mutable -> 변경 가능
// immutable Dictionary
IReadOnlyDictionary<int, string> dicss = dics.ToImmutableDictionary<int, string>();
//dicss = new()
//{
// [1] = "aaaa",
// [2] = "bbbb",
// [3] = "cccc",
//}; //immutable -> 변경 불가능
// Dictionary_mutable 출력
ptr = dics.GetEnumerator();
while (ptr.MoveNext())
{
Write($" {ptr.Current}");
}
WriteLine();
// Dictionary_immutable 출력
ptr = dicss.GetEnumerator();
while (ptr.MoveNext())
{
Write($" {ptr.Current}");
}
WriteLine();
----
Nullable
1. int? suja = null;
int? suja = null;
2. //#nullable enable
WriteLine(suja);
//#nullable disable
#nullable enable
WriteLine(suja);
#nullable disable
3. Edit Project File - <Nullable>enable</Nullable>
<Nullable>enable</Nullable>
-----
Null 처리
1. C# 1.0: If 활용
string? strs = null;
if(strs == null)
{
strs = "rule service - helele";
}
WriteLine(strs);
<result>
rule service - helele
2. C# 3.0: ?? - null이라면
string? strs = null;
strs = strs??"abcdefg"; // ?: nullable, ??: null이면
WriteLine(strs);
<result>
abcdefg
3. C# 6.0: . - ERROR가 안 난다면
string? strs = null;
WriteLine(strs?.ToString()); // .: error가 안 난다면 출력
<result>
4. C# 8.0: !(bang solution) - run-time service(compiler X)
string? str0 = null;
string? strs = str0!; //!(bang solution)
strs = strs??"abcdefg"; // ?: nullable, ??: null이면 C# 3.0
WriteLine(strs!.ToString()); //meta-program(dynamic program) - run-time service
int? suja0 = null;
int? suja = suja0!; //!(bang solution)
suja = suja ?? 12345;
WriteLine(suja!.ToString()); //meta-program(dynamic program) - run-time service
<result>
abcdefg
12345
-----
Stack invarience(immutable) - immutable + stack-operation
// invarience(immutable) - single object -> 변경 불가능
Person person = new Person(11,"leebok1", true);
WriteLine(person.GetHashCode());
person = person with { Name = "helele"}; // invarience 바꾸기 위해 with operation 사용
WriteLine(person.GetHashCode()); // 값 바뀜 -> hashcode(번지수) 다름 ==> 이름만 같고 다른 object
Person otherPerson = person with { Name = "helele and hevele" }; // hashcode 다르기 때문에 새로운 변수 생성
WriteLine(otherPerson);
// stack invarience(immutable)
var stack = ImmutableStack<int>.Empty; // push해도 상태는 empty -> ERROR
foreach (var kkk in Enumerable.Range(1, 10))
{
stack = stack.Push(kkk); // immutable + stack-operation
WriteLine(stack.Peek()); // peek: 들여다보는 operation, pop: 추출 operation
}
foreach (var kkk in stack)
{
WriteLine(stack.Pop());
}
ImmutableStack
ImmutableStack<int> s1 = ImmutableStack<int>.Empty; // s1이라는 상태를 만듦 (start point = head)
ImmutableStack<int> s2 = s1.Push(1);
ImmutableStack<int> s3 = s2.Push(2);
ImmutableStack<int> s33 = s2.Pop();
ImmutableStack<int> s333 = s33.Push(300);
ImmutableStack<int> s4 = s3.Push(3); //insert-operating
ImmutableStack<int> s44 = s3.Pop(); // 결과에 영향 미치지 않음 -> single source of truth
ImmutableStack<int> s444 = s44.Push(400);
ImmutableStack<int> s5 = s4.Push(4);
WriteLine(s1);
WriteLine(s2.Peek()); //pop(): operation을 pop -> result가 dataX / peek(): result = data
WriteLine(s3.Peek());
WriteLine(s4.Peek());
WriteLine(s5.Peek());
WriteLine(s33);
WriteLine(s44);
//WriteLine(s44.Peek()); ERROR: stack이 비어있기 때문
WriteLine(s333.Peek());
WriteLine(s444.Peek());
<result>
System.Collections.Immutable.ImmutableStack`1[System.Int32]
1
2
3
4
System.Collections.Immutable.ImmutableStack`1[System.Int32]
System.Collections.Immutable.ImmutableStack`1[System.Int32]
300
400
-----
Injection of Control (IoC)
Customer customer = new("leebok"); // record -> json packet 형태
WriteLine(customer);
customer.Add(); //business service - call (business object만 변경)
//business object (business layer/tier)
public record Customer(string Name)
{
//SqlDal dal = new SqlDal();
//OracleDal dal = new OracleDal();
//MySqlDal dal = new MySqlDal();
//PostGreSqlDal dal = new();
IDal dal; // Injector(pointer, selector): Interface
// injector는 injection service(injector에서 초기화)에서 사용해야 함
public void Add()
=> dal.Add();
};
public interface IDal // Dal: Data Access Layer
{
public void Add(); // declare statement(partial method)
}
//data object (data layer/tier)
public record SqlDal() : IDal //: 계승(expand) - Interface(IDal)을 이용하여 tightly-coupled -> loosely-coupled
{
public void Add()
=> WriteLine($"Public record SQLDal() :: Add()");
}; // Sql Data Layer
public record SqliteDal() : IDal
{
public void Add()
=> WriteLine($"Public record SqliteDal() :: Add()");
};// PostGresQL Data Layer
public record OracleDal() : IDal
{
public void Add()
=> WriteLine($"Public record OracleDal() :: Add()");
};// Oracle Data Layer
public record MySqlDal() : IDal
{
public void Add()
=> WriteLine($"Public record MySqlDal() :: Add()");
};// MySql Data Layer
public record PostGreSqlDal() : IDal
{
public void Add()
=> WriteLine($"Public record PostGreSqlDal() :: Add()");
};// PostGresQL Data Layer
뭔 소린지 진심 1도 모르겠음
//Customer customer = new(new OracleDal()); // record -> json packet 형태
//DB <- Container <- component <- code <- CPU
IUnityContainer container = new UnityContainer();
container.RegisterType<IDal, SqlDal>();
container.RegisterType<Customer>();
Customer customer = container.Resolve<Customer>();
customer = customer with { Name = "leebok" };
WriteLine(customer);
customer.Add(); //business service - call (business object만 변경)
container.RegisterType<IDal, OracleDal>();
container.RegisterType<Customer>();
customer = container.Resolve<Customer>();
customer = customer with { Name = "leebok2" };
WriteLine(customer);
customer.Add(); //business service - call (business object만 변경)
container.RegisterType<IDal, PostGreSqlDal>();
container.RegisterType<Customer>();
customer = container.Resolve<Customer>();
customer = customer with { Name = "leebok3" };
WriteLine(customer);
customer.Add(); //business service - call (business object만 변경)
public record Customer(IDal dal)
{
public string Name { get; init; } = default(string);
//SqlDal dal = new SqlDal();
//OracleDal dal = new OracleDal();
//MySqlDal dal = new MySqlDal();
//PostGreSqlDal dal = new();
//record로 표현했기 때문에 생략 가능 -> class로 표현할 경우 필요한 code
//IDal dal; // Injector(pointer, selector): Interface
// injector는 injection service(injector에서 초기화)에서 사용해야 함
public void Add()
=> dal.Add();
};
public interface IDal
{
public void Add(); // declare statement(partial method)
}
//data object (data layer/tier)
public record SqlDal() : IDal //: 계승(expand) - Interface(IDal)을 이용하여 tightly-coupled -> loosely-coupled
{
public void Add()
=> WriteLine($"Public record SQLDal() :: Add()");
}; // Sql Data Layer
public record SqliteDal() : IDal
{
public void Add()
=> WriteLine($"Public record SqliteDal() :: Add()");
};// PostGresQL Data Layer
public record OracleDal() : IDal
{
public void Add()
=> WriteLine($"Public record OracleDal() :: Add()");
};// Oracle Data Layer
public record MySqlDal() : IDal
{
public void Add()
=> WriteLine($"Public record MySqlDal() :: Add()");
};// MySql Data Layer
public record PostGreSqlDal() : IDal
{
public void Add()
=> WriteLine($"Public record PostGreSqlDal() :: Add()");
};// PostGresQL Data Layer
<reference>
-----
Delegator
thread coding
- thread: cpu(real-time service) excution의 단위
static void Main(string[] args)
{
//process-level-call(name으로 함수 call): 비용 높음
WriteLine($@"Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
HeleleFunc1();
HeleleFunc2();
//thread-level-call: 비용 낮추기 위해
Thread t1 = new Thread(new ThreadStart(HeleleFunc1)); // ThreadStart: delegate object
Thread t2 = new Thread(new ThreadStart(HeleleFunc2));
// thread는 자동 실행되지 않음 -> 실행 시켜줘야함
t1.Start();
t2.Start();
}
private static void HeleleFunc2()
=> WriteLine($@"2_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
private static void HeleleFunc1()
=> WriteLine($@"1_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
<result>
Thread-Id: 1 Task-Id:
1_Thread-Id: 1 Task-Id:
2_Thread-Id: 1 Task-Id:
1_Thread-Id: 3 Task-Id:
2_Thread-Id: 4 Task-Id:
Thread-level
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
// Synchronose: process-level에서 top/down / ASynchronose: system-level에서 real-time
// thread-level-call: 비용 낮추기 위해
//Thread t1 = new Thread(new ThreadStart(HeleleFunc1)); // ThreadStart: delegate object
Thread t1 = new Thread(HeleleFunc1);
Thread t2 = new Thread(HeleleFunc2);
// thread는 자동 실행되지 않음 -> 실행 시켜줘야함
t1.Start();
t1.Join(); // waitting(t1이 시작되고 끝날 때까지 기다렸다 다음 line 실행), fore-ground thread와 join
t2.Start();
t2.Join();
//process-level-call(name으로 함수 call): 비용 높음
WriteLine($@"Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
HeleleFunc1();
HeleleFunc2();
}
private static void HeleleFunc2()
{
Thread.Sleep(3000);
WriteLine($@"2_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
}
private static void HeleleFunc1()
{
Thread.Sleep(3000);
WriteLine($@"1_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
}
}
}
Delegate-level
using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public delegate void heleDele(); // C# 1.0 delegate -> thread indirect coding 위해 나옴(managed thread)
class Program
{
static void Main(string[] args)
{
// delegate-level-declare
heleDele obj = new heleDele(HeleleFunc1);
heleDele obj2 = new heleDele(HeleleFunc2);
// delegate-level-call (name-call -> process service call ==> fore-ground 실행)
obj();
obj2();
// delegate-level-call (Invoke -> Thread service(foreground-thread) ==> thread id: 1)
obj.Invoke();
// delegate-level-call (BeginInvoke -> ASync Thread service(worker-thread) ==> thread id: 1x)
IAsyncResult result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
// Synchronose: process-level에서 top/down / ASynchronose: system-level에서 real-time
// thread-level-call: 비용 낮추기 위해
// Thread t1 = new Thread(new ThreadStart(HeleleFunc1)); // ThreadStart: delegate object
Thread t1 = new Thread(HeleleFunc1);
Thread t2 = new Thread(HeleleFunc2);
// thread는 자동 실행되지 않음 -> 실행 시켜줘야함
t1.Start();
t1.Join(); // waitting(t1이 시작되고 끝날 때까지 기다렸다 다음 line 실행), fore-ground thread와 join
t2.Start();
t2.Join();
//process-level-call(name으로 함수 call): 비용 높음
WriteLine($@"Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
HeleleFunc1();
HeleleFunc2();
}
// IAsyncResult: threading state
private static void heleleCallBack(IAsyncResult ar)
{
heleDele imsi = (heleDele)ar.AsyncState;
imsi.EndInvoke(ar);
}
private static void HeleleFunc2()
//=> WriteLine($@"2_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
{
Thread.Sleep(3000);
WriteLine($@"2_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
}
private static void HeleleFunc1()
//=> WriteLine($@"1_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
{
Thread.Sleep(3000);
WriteLine($@"1_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
}
}
}
<result>
1_Thread-Id: 1 Task-Id:
2_Thread-Id: 1 Task-Id:
1_Thread-Id: 1 Task-Id:
1_Thread-Id: 6 Task-Id:
1_Thread-Id: 3 Task-Id:
1_Thread-Id: 4 Task-Id:
1_Thread-Id: 5 Task-Id:
1_Thread-Id: 7 Task-Id:
1_Thread-Id: 9 Task-Id:
2_Thread-Id: 8 Task-Id:
Thread-Id: 1 Task-Id:
1_Thread-Id: 1 Task-Id:
2_Thread-Id: 1 Task-Id:
///// 여기서부터 error난 것 같음 /////
Procedure 비용 높음 -> 없애라
using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public delegate void heleDele(); // C# 1.0 delegate -> thread indirect coding 위해 나옴(managed thread)
class Program
{
static void Main(string[] args)
{
// delegate-level-declare
heleDele obj = delegate () // C# 2.0 anonymouse function(이름 없는 함수)
{
Thread.Sleep(3000);
WriteLine($@"2_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
};
heleDele obj2 = delegate()
{
Thread.Sleep(3000);
WriteLine($@"1_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
};
// delegate-level-call (name-call -> process service call ==> fore-ground 실행)
obj();
obj2();
// delegate-level-call (Invoke -> Thread service(foreground-thread) ==> thread id: 1)
obj.Invoke();
// delegate-level-call (BeginInvoke -> ASync Thread service(worker-thread) ==> thread id: 1x)
IAsyncResult result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
// Synchronose: process-level에서 top/down / ASynchronose: system-level에서 real-time
// thread-level-call: 비용 낮추기 위해
// Thread t1 = new Thread(new ThreadStart(HeleleFunc1)); // ThreadStart: delegate object
//Thread t1 = new Thread(HeleleFunc1);
//Thread t2 = new Thread(HeleleFunc2);
//// thread는 자동 실행되지 않음 -> 실행 시켜줘야함
//t1.Start();
//t1.Join(); // waitting(t1이 시작되고 끝날 때까지 기다렸다 다음 line 실행), fore-ground thread와 join
//t2.Start();
//t2.Join();
//process-level-call(name으로 함수 call): 비용 높음
WriteLine($@"Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
WriteLine("press any key -> EXIT_fore-groud-thread"); // fore-groud가 멈추는 것 방지
ReadKey();
//HeleleFunc1();
//HeleleFunc2();
}
// IAsyncResult: threading state
private static void heleleCallBack(IAsyncResult ar)
{
heleDele imsi = (heleDele)ar.AsyncState;
imsi.EndInvoke(ar);
}
//private static void HeleleFunc2()
////=> WriteLine($@"2_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
//{
// Thread.Sleep(3000);
// WriteLine($@"2_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
//}
//private static void HeleleFunc1()
////=> WriteLine($@"1_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
//{
// Thread.Sleep(3000);
// WriteLine($@"1_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
//}
}
}
<result>
2_Thread-Id: 1 Task-Id:
1_Thread-Id: 1 Task-Id:
2_Thread-Id: 1 Task-Id:
Thread-Id: 1 Task-Id:
press any key -> EXIT_fore-groud-thread
2_Thread-Id: 3 Task-Id:
2_Thread-Id: 5 Task-Id:
2_Thread-Id: 6 Task-Id:
2_Thread-Id: 4 Task-Id:
2_Thread-Id: 7 Task-Id:
Delegate -> Action
using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public delegate void heleDele(); // C# 1.0 delegate -> thread indirect coding 위해 나옴(managed thread)
class Program
{
static void Main(string[] args)
{
// delegate-level-declare
Action obj = delegate () // C# 2.0 anonymouse function(이름 없는 함수)
{
Thread.Sleep(3000);
WriteLine($@"2_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
};
Action obj2 = delegate ()
{
Thread.Sleep(3000);
WriteLine($@"1_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
};
// local function
void heleleCallBack(IAsyncResult ar)
{
Action imsi = (Action)ar.AsyncState;
imsi.EndInvoke(ar);
};
// delegate-level-call (name-call -> process service call ==> fore-ground 실행)
obj();
obj2();
// delegate-level-call (Invoke -> Thread service(foreground-thread) ==> thread id: 1)
obj.Invoke();
// delegate-level-call (BeginInvoke -> ASync Thread service(worker-thread) ==> thread id: 1x)
IAsyncResult result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
//process-level-call(name으로 함수 call): 비용 높음
WriteLine($@"Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
WriteLine("press any key -> EXIT_fore-groud-thread"); // fore-groud가 멈추는 것 방지
ReadKey();
}
}
}
<result>
2_Thread-Id: 1 Task-Id:
1_Thread-Id: 1 Task-Id:
2_Thread-Id: 1 Task-Id:
Thread-Id: 1 Task-Id:
press any key -> EXIT_fore-groud-thread
2_Thread-Id: 3 Task-Id:
2_Thread-Id: 6 Task-Id:
2_Thread-Id: 4 Task-Id:
2_Thread-Id: 5 Task-Id:
2_Thread-Id: 7 Task-Id:
Ramda Expression (C# 3.0)
using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public delegate void heleDele(); // C# 1.0 delegate -> thread indirect coding 위해 나옴(managed thread)
class Program
{
static void Main(string[] args)
{
// delegate-level-declare
Action obj = () => // C# 3.0 Lambda expression
{
Thread.Sleep(3000);
WriteLine($@"2_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
};
Action obj2 = () =>
{
Thread.Sleep(3000);
WriteLine($@"1_Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
};
// local function
void heleleCallBack(IAsyncResult ar)
{
Action imsi = (Action)ar.AsyncState;
imsi.EndInvoke(ar);
};
// delegate-level-call (name-call -> process service call ==> fore-ground 실행)
obj();
obj2();
// delegate-level-call (Invoke -> Thread service(foreground-thread) ==> thread id: 1)
obj.Invoke();
// delegate-level-call (BeginInvoke -> ASync Thread service(worker-thread) ==> thread id: 1x)
IAsyncResult result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
result = obj.BeginInvoke(new AsyncCallback(heleleCallBack), obj);
//process-level-call(name으로 함수 call): 비용 높음
WriteLine($@"Thread-Id: {Thread.CurrentThread.ManagedThreadId} Task-Id: {Task.CurrentId}");
WriteLine("press any key -> EXIT_fore-groud-thread"); // fore-groud가 멈추는 것 방지
ReadKey();
}
}
}
<result>
2_Thread-Id: 1 Task-Id:
1_Thread-Id: 1 Task-Id:
2_Thread-Id: 1 Task-Id:
Thread-Id: 1 Task-Id:
press any key -> EXIT_fore-groud-thread
2_Thread-Id: 4 Task-Id:
2_Thread-Id: 6 Task-Id:
2_Thread-Id: 3 Task-Id:
2_Thread-Id: 5 Task-Id:
2_Thread-Id: 7 Task-Id:
-----
de-coupled
1. class와 class: Interface
2. ~와 ~
3. ~와 ~
'.Net 교육' 카테고리의 다른 글
8/17(월) 6일차 C#.Net 교육 (0) | 2021.08.17 |
---|---|
8/13(금) 5일차 C#.Net 교육 (0) | 2021.08.13 |
8/11(수) 3일차 C#.Net 교육 (0) | 2021.08.11 |
MVC application (0) | 2021.08.10 |
8/10(화) 2일차 C#.Net 교육 (0) | 2021.08.10 |