我正在开发一款小型游戏,我可以使用RTB模拟控制台。游戏本身运行LUA脚本,调用API函数输出到控制台。然后,此API将触发一个事件(使用caliburn micro),该事件由控制台类获取,并且消息将附加到RTB。
我现在希望能够在消息中的每个字符之间添加一个小延迟,从而使其更具效果。不幸的是,我已经打了一些砖墙。虽然我可以使用第二个线程和睡眠或计时器轻松地在角色之间添加延迟。我遇到的问题是,如果脚本向控制台发送两条消息,则第二条消息与延迟消息同时处理,因此文本出现乱码。
我所追求的是在消息中打印字符之间有一点延迟的方法,但是在处理后续调用输出到控制台之前等待它完成。
线程是我在现实中仅在基本层面上使用的东西。我想我理解基本概念。但是这个给了我一些问题。如果我尝试等待延迟线程完成它阻塞主线程并且没有输出(因此整个程序永远挂起)
希望我能够很好地解释这一点。任何帮助表示赞赏。
答案 0 :(得分:2)
如果你不想锁定,你想在这里使用的是一个队列,parralelQueue。
事件处理程序只是将消息添加到队列中,只要队列中有项目,单独的进程将读取一个并慢慢打印它。以下是如何使用parralelQueue执行此操作的示例。
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;
ConcurrentQueue<string> MessageQueue;
ManualResetEventSlim queRefilled = new ManualResetEventSlim(false);
bool writerStopper;
Task messageWriter;
private void MessageDispatcher() //this is going to be the writing thread
{
while (!writerStopper)
{
if(MessageQueue.Count ==0)
{
//loop every 200 seconds to check the writerStopper
if (!queRefilled.Wait(200)) //wait until we know that a message has been added, this was done to minimize latency.
continue;
queRefilled.Reset();
continue;
}
string message;
if (MessageQueue.TryDequeue(out message))
yourWriteMethod(message); //here you can call your existing writer
}
}
//call this to add a message to the screen
public void QueueToScreen(string message)
{
MessageQueue.Enqueue(message);
queRefilled.Set(); //set the flag so that the writer knows that there are messages
}
public void start()
{
MessageQueue = new ConcurrentQueue<string>();
writerStopper = false;
messageWriter = new Task(MessageDispatcher);
messageWriter.Start();
}
public void stop()
{
writerStopper = true;
MessageQueue = null;
}
此代码尝试使用ManualResetEventSlim最小化延迟。你也可以只使用thread.sleep,但后来反应会稍微减少。我也忽略了cancelTokens因为懒惰。如果你永远不想在主应用程序之前停止脚步,你可以使用while(true)和queRefilled.Wait()来无限期地阻止;