這樣簡單!這是我的一個嘗試,它要求函數通過自身的pausable部分使用Pause()函數。實現可以使用的線程類
using System;
using System.Threading;
class BlackThread {
private bool paused;
private Thread innerThr;
// ---
public bool IsAlive {
get {
return innerThr.IsAlive;
}
}
// ===
public void SetAndGo (ThreadStart start) {
paused = false;
innerThr = new Thread(start);
innerThr.Start();
WaitForIt();
}
// ---
public void Pause() {
paused = true;
while (paused);
}
public void Unpause() {
paused = false;
}
public void WaitForIt() {
while(!paused && IsAlive);
}
public void Continue() {
Unpause();
WaitForIt();
}
}
class MainClass {
static void pausableFunction (BlackThread self) {
Console.WriteLine("* Waiting...");
self.Pause();
Console.WriteLine("* Doing stuff.");
self.Pause();
Console.WriteLine("* Finished!");
}
static void Main() {
BlackThread noir = new BlackThread();
noir.SetAndGo(() => pausableFunction(noir));
while (noir.IsAlive) {
Console.Write("> ");
Console.ReadKey();
noir.Continue();
}
}
}
可悲的是,這不是一個可以隨時被暫停,但對於需要等待外處理功能的線程能夠繼續。就像一個遊戲暴民的行動,它需要它的框架在繪製循環之前被繪製循環繪製,並且暴民的A.I.在遊戲的主循環中被處理。
我想它會使它成爲某種僞線程?無論如何。
它將允許暴徒在每個循環中逐位處理此動作,而不是在A.I中進行級聯檢查。像...
if mob is doing action {
if mob has already done this previous part of the action {
do the following part
}
}
...它寧願是這樣的,在一個線程:
do the first step of the action
Wait for it to be rendered...
do the following step of the action
Wait for it to be rendered...
do the last step of the action
(Action ends here, no need to wait for anything anymore)
現在,我實現了我無法弄清楚如何修復一個bug。當它應該取消暫停BlackThread時,它在使用它的函數(在本例中爲pausableFunction())中保持暫停狀態。我想這是因爲該實例是如何傳遞的?
如果這是我的猜測 - 也就是說,某些東西(我猜想它是布爾暫停)是通過值而不是引用傳遞的 - 我該如何解決它?我真的習慣了C和C++的指針,所以有時當我在C#中處理一個對象在作用域之間的值時,我會有點糾結。
這這裏是代碼的一個版本的作品,原型說:
using System;
using System.Threading;
class Program {
static bool paused;
static void Pause() {
paused = true;
while (paused);
}
static void Unpause() {
paused = false;
}
static void WaitForIt(Thread waited) {
while(!paused && waited.IsAlive);
}
static void Continue (Thread ToStop) {
Unpause();
WaitForIt(ToStop);
}
static void SetAndGo (out Thread thread, ThreadStart Start) {
thread = new Thread(Start);
thread.Start();
WaitForIt(thread);
}
// ---
static void thr (string chant) {
// Console.WriteLine("Waiting...");
// Pause();
// Console.WriteLine("{0}", chant);
// Pause();
// Console.WriteLine("Well, I'm finished!");
Console.WriteLine("I'm finished!");
}
static void Main() {
// Thread tt = new Thread(() => thr());
// tt.Start();
// WaitForIt(tt);
Thread tt;
SetAndGo(out tt, (() => thr("I'm doing stuff.")));
while (tt.IsAlive) {
Console.Write("> ");
Console.ReadKey();
Continue(tt);
}
}
}
我只是不使用它,因爲我寧願有負責特定類的一切對於這個問題,這也會增強可讀性。
Spinwait,例如'while(!paused && IsAlive);'應該*真的被避免。您應該執行阻止等待。 – Servy
@Servy很好,那麼你會推薦什麼呢?我想過使用Monitor Pulse和Wait,但是我不太清楚。 – Mutoh
有相當多的選項,包括'ManualResetEvent'或'Semaphore'。 – Servy