Delegate = 대리자 말그대로 대신 실행시켜주는것 invoke나 event를 쓰기위해선 필수
그외에도 비동기 계열들을 동기 계열처럼 쓸 수 있게 해준다
예제1
namespace namespace1
{
public delegate void delegate_sender(string text_buff);
public static class class1
{
void Main()
{
class2 cl = new class2(); //클래스 생성
cl.delegate_handle = new delegate_sender(text_set); //대리시킬 함수 명시
}
set_text(string text)
{
messagebox.show(text);
}
}
class class2 //이벤트를 실행할 클래스2
{
public static delegate_sender delegate_handle;
void main()
{
delegate_handle("test");//델리게이트 동작
}
}
}
이벤트
용도: 이벤트가 발생하면 이벤트 리스너에 등록된 곳에서 모두 동작을 실시합니다
namespace namespace1
{
public delegate void delegate_sender(string text_buff);
public static class class1
{
void Main()
{
class2 cl = new class2(); //클래스 생성
cl.event_handle += new delegate_sender(show_text); //이벤트 등록
}
show_text(string text)
{
messagebox.show(text);
}
}
class class2 //이벤트를 실행할 클래스2
{
public event delegate_sender event_handle; //이벤트 리스너 생성
void main()
{
event_handle("test");//이벤트 동작
}
public void CallEvent(string text)//이벤트 핸들은 반드시 해당 클래스에서 호출해야 하기 때문에 외부에서 호출시 이런식으로 호출
{
event_handle("test");//이벤트 동작
}
}
}
Invoke함수
존나 옛날에 내가 다 정리해놨었네;
요새 프로그래밍 다시 시작하면서 복습중이다
Invoke(Delegate)
//컨트롤의 내부 창 핸들이 있는 스레드에서 지정된 대리자를 실행합니다.
Invoke(Delegate, Object[])
//컨트롤의 내부 창 핸들이 있는 스레드에서 특정 인수 목록을 사용하여 지정된 대리자를 실행합니다.
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox_log.InvokeRequired)
{
//delegate_sender d = new delegate_sender (SetText);
//this.Invoke(new delegate_sender (SetText), new object[] { text });
//this.Invoke(new Action(delegate () {할일 }));
//string _return ="";
//this.Invoke(new Action(delegate () { _return = this.textBox.Text; }));
this.Invoke(new delegate_sender(SetText), text);
}
else
{
this.textBox.Text = text;
}
}
이건 윈폼예제
간단한 요약
멀티스레드에서 가장 문제가 되는 클립보드 접근에 대한것
핸들이 static이므로 그냥 막 쓸수 있다
public delegate void de_set_clip(string text); //입력예제
public delegate string de_get_clip(); //출력예제
public partial class Form1: Form
{
public void set_clip(string input) //입력함수
{
this.Invoke(new Action(delegate () {
Clipboard.SetText(input);
}));
}
public string get_clip() //출력함수
{
String _return ="";
this.Invoke(new Action(delegate () {
_return=Clipboard.GetText();
}));
return _return;
}
public Form1() //사용할 폼
{
clip.de_set_clip_handle = new de_set_clip(set_clip);
clip.de_get_clip_handle = new de_get_clip(get_clip);
InitializeComponent();
}
public static class clip
{
public static de_set_clip de_set_clip_handle; //이걸 다른 폼에서 사용
public static de_get_clip de_get_clip_handle;
}
}
존나 옛날에 짠거들이라 리메이크 해야할듯
delegate기반 계열로 Action이 있다
위쪽이 이벤트 기반이라면 이쪽은 비동기 리턴에 사용
비동기 리턴 예제
public void Login() //외부에서 리턴안쓰고 호출할때 사용
{
Login(success=> { });
}
public void Login(System.Action<bool> successCallback)
{
if (로그인 하는데 성공)
{
successCallback.Invoke(true);
}
else
{
successCallback.Invoke(false);
}
}
public void Start()
{
Login(success =>
{
if (success)
{
//성공했을경우 처리
}
else
{
//실패했을경우 처리
}
});
}
이벤트 핸들러 예제
public event System.EventHandler StateChanged;
public void OnStateChanged()
{
//sender는 누가 발생시켰는지, System.EventArgs.Empty는 리턴밸류를 할당하지 않겠다는 뜻
StateChanged?.Invoke(sender:this, System.EventArgs.Empty);
Debug.Log("상태가 전환됨");
}
public void Start()
{
StateChanged+=OnStateChanged;
}
유니티 전용 이벤트가 있다
유니티 이벤트 기능
public class CustomInteface
{
[System.Serializable]
public class Vector3Event : UnityEngine.Events.UnityEvent<Vector3> { }
//public class VoidEvent : UnityEngine.Events.UnityEvent { }
//public UnityEvent OnEvent; //void 타입
public Vector3Event OnEvent;
void Start()
{
//함수를 붙일때
OnEvent.AddListener (Draw);
//호출
OnEvent.Invoke(transform.position);
}
//붙일함수
void Draw(Vector3 pos)
{
Debug.Log ("pos:"+pos);
}
}
public IEnumerator IndexChengedChecker()
{
while (true)
{
var indexPrevious = index;
yield return new WaitUntil(() => index != indexPrevious);
//상태 변경됨
//event.Invoke();
}
}