将线程发送到休眠状态直到事件发生

时间:2017-03-13 11:48:51

标签: c# multithreading

我有一个包含2个线程的多线程程序。

一个线程 正在检测USB插入和移除。

第二个帖子 负责将文件传输到USB(在USB插入事件中)。将所有文件成功复制到USB后,文件复制线程( 第二个线程 )应进入“成功复制”状态并保持在那里,直到USB被删除。移除USB后,isUSBInsterted标志设置为FALSE,文件复制线程( 第二线程 )进入IDLE状态。

 public enum FileTransferStates { Idle = 0, FileCopyingState = 1, SuccessfullyCopiedState = 2 }

    public void ExecuteUSBFileTransfer()
    {
        switch (CurrentState)
        {
            case FileTransferStates.Idle:
                IdleState();
                return;


            case FileTransferStates.FileCopyingState:

                FileCopyingState();
                ExecuteUSBFileTransfer();
                break;

            case FileTransferStates.SuccessfullyCopiedState:

                SuccessfullyCopiedState();
                ExecuteUSBFileTransfer();
                break;

            default:
                return;
        }
    }

    private void SuccessfullyCopiedState()
    {
       //Current state is "FileTransferStates.SuccessfullyCopiedState"

        if (!USB.isUSBInsterted)
            CurrentState = FileTransferStates.Idle; //Resetting the State if the USB is removed        
    }

问题:目前,如果线程已进入ExecuteUSBFileTransfer() ,我会一次又一次地调用父方法(SuccessfullyCopiedState())。我认为这是CPU资源的浪费。此外,USB可能会长时间插入。所以,我希望线程在此持续时间内休眠,直到USB没有被删除。如何保留SuccessfullyCopiedState()而不检查USB移除而不浪费资源?

PS:基本上,我想在SuccessfullyCopiedState()方法中将文件复制线程发送到休眠阶段,直到USB未被删除。

1 个答案:

答案 0 :(得分:2)

您正在寻找:

AutoResetEvent(ManualResetEvent)

简单地说:这些将允许你“冻结”一个线程,直到它从另一个线程收到“go”。

在另一个问题的答案中,ErenErsönmez有一个完整的example,它使用了2个工作线程,但仍然很容易掌握。

基本上你有这个AutoResetEvent对象,它会在你调用.WaitOne()时阻止线程的执行。一旦从您喜欢的任何线程中调用.Set(),该“阻止”将被重置。

示例:

static readonly AutoResetEvent fileCopyEvent = new AutoResetEvent(false);

bool keepFileCopyThreadAlive = true;
void FileCopyThread()
{
    while (keepFileCopyThreadAlive)
    {
        fileCopyEvent.WaitOne(); 
        if (!keepFileCopyThreadAlive) return; // Exit thread if told to.
        Console.WriteLine("Copying files...");
        Thread.Sleep(1000); // Do your stuff here
        Console.WriteLine("Done copying files, waiting for USB Thread.");
    }
}

此时您只需从USB线程中调用:fileCopyEvent.Set();即可。 这将释放“阻止”并执行fileCopyEvent.WaitOne();以下的任何内容。由于这是一个AutoResetEvent对象,它将自动返回到“阻塞”状态,您无需执行任何其他操作。该循环将强制代码返回.WaitOne(),并为您下次调用.Set()做好准备。

退出线程就像设置keepFileCopyThreadAlive = false;然后调用通常的.Set()一样简单。因为有一个keepFileCopyThreadAlive == false

退出循环的检查

注意:上面的代码未经测试,现在没有可用的编译器。