我很怀念,开发了一个基于文本的 Adventure Game Creator IDE,它有一个 Windows 窗体,可以在富文本框中显示消息。
我编写了一个消息调度程序类,它将使用 BackgroundWorker 将文本(房间描述和消息)从流中发送到文本框。这工作得很好,但我有一个小问题......
我需要做的是能够在我选择的任意秒数内暂停/保持后台工作人员。这样做的原因是,在冒险脚本语言中,有一个名为的语句HOLD
将暂停游戏 n 秒。
问题是我正在使用消息调度程序显示一条消息(蛇过来咬你,你死了......),但在消息显示之前正在执行 HOLD 语句。这对我没有好处,因为我需要先显示消息然后暂停游戏。
在 HOLD 方法的执行上下文中,我得到了:
Thread.CurrentThread.Join( _value * 10 );
我也试过:
Thread.Sleep( _value * 10 );
这些都不起作用,所以我问是否可以将 BackgroundWorker 暂停任意秒数?
** 编辑 **
添加了以下代码BackgroundWorker
:
public delegate void OnReceiveData( object sender, StreamWatcherEventArgs e );
public class StreamWatcher
{
public event OnReceiveData DataReceived = delegate { };
private Stream _stream;
public StreamWatcher( Stream stream )
{
_stream = stream;
CreateWatcherThread();
}
private void CreateWatcherThread()
{
var bw = new BackgroundWorker();
bw.DoWork += ( sender, args ) =>
{
while ( true )
{
if ( _stream.Length > 0 )
{
Thread.CurrentThread.Join( 50 );
byte[] buf = new byte[ _stream.Length ];
_stream.Seek( 0, SeekOrigin.Begin );
_stream.Read( buf, 0, buf.Length );
string data = ASCIIEncoding.ASCII.GetString( buf );
DataReceived( this, new StreamWatcherEventArgs( data ) );
_stream.SetLength( 0 );
}
}
};
bw.RunWorkerAsync(); ;
}
}
只是为了感兴趣,这是正在执行的脚本:
IF ( VERB(7) AND NOUN(5) ) MESSLF(14) HOLD(200) EXIT END
这基本上是说,如果我输入“GET SNAKE”,它将通过消息调度程序向文本框显示一条消息,然后暂停游戏 2 秒。
问题是在显示消息之前首先发生暂停,因为暂停发生在主线程上。
这是DataReceived
事件处理程序:
_watcher.DataReceived += ( s, e ) =>
{
if ( rtbOutput.InvokeRequired )
{
rtbOutput.Invoke( new Action( () =>
{
rtbOutput.AppendText( e.Data );
rtbOutput.ScrollToCaret();
} ) );
}
else
{
rtbOutput.AppendText( e.Data );
rtbOutput.ScrollToCaret();
}
};