Coroutines 및 Fibers으로 인해 가능합니다.
스레드는 운영 체제 스케줄러가 독립적으로 관리 할 수있는 프로그래밍 된 명령어의 최소 시퀀스이지만 단일 스레드를 공유하는 응용 프로그램 내에 coroutine이 존재할 수 있습니다. 즉, 하나의 루틴은 다른 루틴이 실행되는 동안 해당 트랙에서 멈출 수 있고, 중단 된 지점에서 다시 같은 스레드 내에서 재개 할 수 있습니다.
외관상으로 무해한 속성을 설정했을 때 우리가 상상했던 것보다 훨씬 더 많은 일이 발생했습니다. this.Left
및 this.Right
.
질문에서 코드 예제에 약간의 로깅을 추가하면이 문제가 발생할 수 있습니다. 또한 — 이후 아래 예제에서 Thread.Sleep(75)
호출을 제거하고 이전 지점에서 더 긴 수면을 추가했습니다. — 수면을 다른 함수로 가져 오는 것이 아니라 this.Left
및 this.Right
을 호출하는 것을 볼 수 있습니다. (또한, 여전히 잠이없는 형태를 흔들하는) :
protected override void WndProc(ref Message m)
{
if (_logWndProc)
listBox1.Items.Add(string.Format("WndProc on thread {0}", Thread.CurrentThread.ManagedThreadId));
base.WndProc(ref m);
}
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
_logWndProc = true;
Thread.Sleep(2000);
listBox1.Items.Add(string.Format("After sleep on thread {0} (see any WndProc logs before this line?!!!)", Thread.CurrentThread.ManagedThreadId));
for (int i = 0; i < 5; i++)
{
listBox1.Items.Add(string.Format("Right {0} on thread {1}", i, Thread.CurrentThread.ManagedThreadId));
this.Left += 10;
listBox1.Items.Add(string.Format("Left {0} on thread {1}", i, Thread.CurrentThread.ManagedThreadId));
this.Left -= 10;
}
_logWndProc = false;
}
private bool _logWndProc = false;
로그 : 양식은`Paint`을 발사하지 않고도 이동할 수 있습니다
. 여전히 나쁜 생각입니다. – SLaks
@SLaks 나는 그것이 좋은 생각이라는 것을 전혀 말하지 않고있다. 나는이 일을하게하는 도대체 무슨 일이 일어나고 있는지 알고 싶다. –
어딘가에 'DoEvents'또는 일부 도덕적으로 상응하는 것이있을 수 있습니다. – Servy