Pause a BackgroundWorker for n-seconds

陌路散爱 提交于 2019-12-08 10:42:44

问题


I was feeling nostalgic and have developed a text based Adventure Game Creator IDE, which has a Windows Form that displays messages to a rich text box.

I have written a message dispatcher class that will send text (room descriptions and messages) from a stream to the text box using a BackgroundWorker. This works brilliantly, but I am having a small problem...

I need to do is be able to pause/hold the Background worker for any number of seconds of my choosing. The reason for this is that, in the adventure scripting language, there is a statement called HOLD which will pause the game for n-seconds.

The problem is that I am displaying a message using the message dispatcher (The snake comes over and bites you and you die....), but the HOLD statement is being executed BEFORE the message gets displayed. This is no good for me as I require the message to be displayed FIRST and then pause the game.

In the execution context for the HOLD method I have got:

Thread.CurrentThread.Join( _value * 10 );

I have also tried:

Thread.Sleep( _value * 10 );

Neither of these work, so I am asking whether it is possible to pause the BackgroundWorker for any number of seconds?

** EDIT **

Added the code for the 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(); ;

    }

}

Just for interest this is the script being executed:

IF ( VERB(7) AND NOUN(5) ) MESSLF(14) HOLD(200) EXIT END

This basically says if I type "GET SNAKE" it will display a message to the text box via the message dispatcher and then pause the game for 2 seconds.

The problem is the pause occurs first BEFORE the message is displayed, because the pause is occurring on the main thread.

Here is the DataReceived event handler:

_watcher.DataReceived += ( s, e ) =>
{
    if ( rtbOutput.InvokeRequired )
    {
        rtbOutput.Invoke( new Action( () =>
        {
            rtbOutput.AppendText( e.Data );
            rtbOutput.ScrollToCaret();
        } ) );
    }
    else
    {
        rtbOutput.AppendText( e.Data );
        rtbOutput.ScrollToCaret();
    }
};

来源:https://stackoverflow.com/questions/18786802/pause-a-backgroundworker-for-n-seconds

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!