我有一个包含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未被删除。
答案 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
注意:上面的代码未经测试,现在没有可用的编译器。