このようにシンプル!これは私の試みであり、スレッド化する関数は、一時停止可能なセクションでそれ自体を介して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();
}
}
}
残念ながら、これはいつでも一時停止できるものではなく、外部処理を続行できるようになるまで待機する必要がある関数のスレッドです。ゲームの暴徒によるアクションのように、フレームを描画ループで描画してから続行する必要があり、暴徒のAIはゲームのメインループで処理されます。
ある種の疑似スレッドになると思いますか?ともかく。
これにより、暴徒はAIでチェックをカスケードする代わりに、ループごとにこのアクションを少しずつ処理できるようになります...
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)
今、私の実装には修正方法がわからないバグがあります。BlackThreadの一時停止を解除することになっている場合、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);
}
}
}
読みやすさも向上させるために、特定のクラスをすべて担当したいので、使用していません。