标签: waitone

如何取消阻止在AutoResetEvent对象上调用WaitOne方法的线程?

下面是一个具有'SomeMethod'方法的类,它说明了我的问题.

class SomeClass
{
    AutoResetEvent theEvent = new AutoResetEvent(false);
    // more member declarations

    public void SomeMethod()
    {
        // some code
        theEvent.WaitOne();
        // more code
    }
}
Run Code Online (Sandbox Code Playgroud)

该方法设计为线程安全的,并将在不同的线程中调用.现在我的问题是如何在任何时间点取消阻止在'theEvent'对象上调用'WaitOne'方法的所有线程?这个要求经常出现在我的设计中,因为我需要能够优雅地停止和启动我的多线程程序.在我看来,启动一个多线程程序相当简单,但很难阻止它.

这是我迄今为止尝试过的,显然有效.但这是标准方法吗?

public void UnblockAll()
{
    do
    {
        theEvent.Set();
    } while (theEvent.WaitOne(0));
}
Run Code Online (Sandbox Code Playgroud)

'UnblockAll'方法是'SomeClass'类的成员.此处使用的技术基于WaitOne方法的MSDN文档.我引用下面文档的相关部分:

如果millisecondsTimeout为零,则该方法不会阻止.它测试等待句柄的状态并立即返回.

在do..while循环中,我调用Set方法.这释放了一个可能由于调用WaitOne方法而被阻塞的线程(在'SomeMethod'方法中编码).接下来,我测试'theEvent'对象的状态,只是为了知道它是否有信号.此测试是通过调用带有超时参数的WaitOne方法的重载版本来完成的.我在调用WaitOne方法时使用的参数为零,根据文档结果,调用立即返回一个布尔值.如果返回值是true,那么"theEvent"的对象信号状态中.如果在'SomeMethod'方法中对'WaitOne'方法的调用至少阻塞了一个线程,则调用'Set'方法(在'UnblockAll'方法中编码)将解除阻塞.因此,在'UnblockAll'方法中do..while语句结束时对'WaitOne'方法的调用将返回false.仅当没有线程被阻止时,返回值才为真.

上述推理是否正确,如果是正确的,该技术是否是处理我的问题的标准方法?我试图主要在.net compact-framework 2.0平台上使用该解决方案.

.net c# waithandle waitone compact-framework2.0

12
推荐指数
2
解决办法
2万
查看次数

即使所有事件都被触发,WaitOne()也会永远等待

假设螺纹形成4个单独的螺纹并等待它们中的每一个直到它们完成.每个线程都会休眠一段时间,只有当共享的Mutex opbject没有被另一个线程占用时才会终止,然后通过它完成的事件发出信号(这是我的代码的简化版本,但在同一个地方失败)

但是,大多数情况下主线程将在WaitOne()中的一个看似随机等待.

此外,我不得不将我的代码的某些部分注释掉,因为它导致了更多的意外行为(也就是说,在每个线程完成主线程之后会以某种方式跳回到for子句并导致IndexOutOfBounds)

class Threading
{
    static Mutex CM;
    static List<Manga> SharedList;
    static ManualResetEvent CEvent = new ManualResetEvent(false);
    static ManualResetEvent Event1 = new ManualResetEvent(false);
    static ManualResetEvent Event2 = new ManualResetEvent(false);
    static ManualResetEvent Event3 = new ManualResetEvent(false);
    static ManualResetEvent Event4 = new ManualResetEvent(false);

   public List<Manga> ThreadedMangaIndexCrawl(int MaxThreads)
   {
       CM = new Mutex(false);
       SharedList = new List<Manga>();

       ManualResetEvent[] evs = new ManualResetEvent[4];
       evs[0] = Event1;    // Event for t1
       evs[1] = Event2;    // Event for t2
       evs[2] = Event3;    // Event …
Run Code Online (Sandbox Code Playgroud)

c# multithreading waitone

5
推荐指数
1
解决办法
1310
查看次数

如何等待BackgroundWorker完成运行另一个BackgroundWorker(C#)?

首先,我还是初学者,所以如果你有耐心,我会很感激:)

我今天一直在为此苦苦挣扎.

问题是,我想运行三个不同的背景工作者.但我想等到一个人完成下一个的运行,依此类推.

每个背景工作者都需要时间来完成.长话短说,问题是,我正在使用WaitOne(),所以每当前面的背景工作者告诉我它已经完成时,我就可以开始运行新的,但是UI线程一直在冻结,直到三个后台工作者完成.

我正在设置一个不同的AutoResetEvent,它是一个负责整个等待和运行的东西.

这是代码:

AutoResetEvent _resetRIEvent = new AutoResetEvent(false);
AutoResetEvent _resetHEvent = new AutoResetEvent(false);
AutoResetEvent _resetSEvent = new AutoResetEvent(false);

await Task.Run(() => bgwTestResInd.RunWorkerAsync());
_resetRIEvent.WaitOne();

await Task.Run(() => bgwTestHipot.RunWorkerAsync());
_resetHEvent.WaitOne();

await Task.Run(() => bgwTestSurge.RunWorkerAsync());
_resetSEvent.WaitOne();

MessageBox.Show("Im done for real.");
Run Code Online (Sandbox Code Playgroud)

此外,是否允许这样做?

private void bgwTestResInd_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    _resetRIEvent.Set();
}


private void bgwTestHipot_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    _resetHEvent.Set();
}


private void bgwTestSurge_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    _resetSEvent.Set();
}
Run Code Online (Sandbox Code Playgroud)

c# backgroundworker autoresetevent waitone

1
推荐指数
1
解决办法
497
查看次数

如何在C#中立即暂停一个线程?

我使用 ManualResetEnvent 来暂停/继续线程。代码示例如下。

private _rstEvent = new ManualResetEvent(true);

public void DoSomeWork()
{
    while(judgementValue)
    {
        _rstEvent.WaitOne();
        ...
    }
}

public void Pause()
{
    _rstEvent.Reset();
}

public void Continue()
{
    _rstEvent.Set();
}
Run Code Online (Sandbox Code Playgroud)

问题是,如果 while 循环很大怎么办,这意味着 while 语句中的每个循环都有很多操作要做。该线程将继续下去,直到遇到下一个_rstEvent.WaitOne();。除了已弃用的挂起之外,还有其他方法可以立即暂停线程吗?

c# multithreading waitone pause

0
推荐指数
1
解决办法
109
查看次数