0

我很怀念,开发了一个基于文本的 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();
    }
};
4

0 回答 0