标签: manualresetevent

.NET中的ManualResetEvent和AutoResetEvent有什么区别?

我已经阅读了关于此的文档,我想我明白了.一个AutoResetEvent当代码经过复位event.WaitOne(),但ManualResetEvent没有.

它是否正确?

.net c# multithreading manualresetevent autoresetevent

511
推荐指数
10
解决办法
17万
查看次数

如何让.NET控制台应用程序运行?

考虑一个Console应用程序,它在一个单独的线程中启动一些服务.它需要做的就是等待用户按Ctrl + C将其关闭.

以下哪项是更好的方法?

static ManualResetEvent _quitEvent = new ManualResetEvent(false);

static void Main() {
    Console.CancelKeyPress += (sender, eArgs) => {
        _quitEvent.Set();
        eArgs.Cancel = true;
    };

    // kick off asynchronous stuff 

    _quitEvent.WaitOne();

    // cleanup/shutdown and quit
}
Run Code Online (Sandbox Code Playgroud)

或者,使用Thread.Sleep(1):

static bool _quitFlag = false;

static void Main() {
    Console.CancelKeyPress += delegate {
        _quitFlag = true;
    };

    // kick off asynchronous stuff 

    while (!_quitFlag) {
        Thread.Sleep(1);
    }

    // cleanup/shutdown and quit
}
Run Code Online (Sandbox Code Playgroud)

c# multithreading sleep manualresetevent

95
推荐指数
5
解决办法
4万
查看次数

ManualResetEventSlim建议等待时间

ManualResetEventSlim状态的MSDN文档

ManualResetEvent与预期等待时间非常短的情况相比,您可以使用此类获得更好的性能.

"很短"多久了?在什么时候使用内核对象的好处ManualResetEvent超过了实例化它的开销?

c# multithreading manualresetevent

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

ManualResetEvent与Thread.Sleep

我实现了以下后台处理线程,其中JobsQueue<T>:

static void WorkThread()
{
    while (working)
    {
        var job;

        lock (Jobs)
        {
            if (Jobs.Count > 0)
                job = Jobs.Dequeue();
        }

        if (job == null)
        {
            Thread.Sleep(1);
        }
        else
        {
            // [snip]: Process job.
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这产生正在进入作业时之间的noticable延迟,当他们实际上开始运行(作业批次在一旦进入,而每个工作只是[比较]小)的延迟是不是一个大问题,但我开始思考这个问题,并做了以下改变:

static ManualResetEvent _workerWait = new ManualResetEvent(false);
// ...
    if (job == null)
    {
        lock (_workerWait)
        {
            _workerWait.Reset();
        }
        _workerWait.WaitOne();
    }
Run Code Online (Sandbox Code Playgroud)

线程添加作业现在锁定_workerWait_workerWait.Set()在完成添加作业时调用.这个解决方案(貌似)立即开始处理工作,延迟完全消失.

我的问题部分是"为什么会发生这种情况?",被认为Thread.Sleep(int)可以比你指定的更长时间地睡眠,部分是"如何ManualResetEvent实现这种性能水平?".

编辑:由于有人询问了排队项目的功能,现在它和目前的完整系统一起.

public void RunTriggers(string data)
{
    lock …
Run Code Online (Sandbox Code Playgroud)

c# multithreading sleep manualresetevent

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

发信号并立即关闭ManualResetEvent是否安全?

我觉得我应该知道答案,但无论如何我都会问,以防万一我犯了一个潜在的灾难性错误.

以下代码按预期执行,没有错误/异常:

static void Main(string[] args)
{
    ManualResetEvent flag = new ManualResetEvent(false);
    ThreadPool.QueueUserWorkItem(s =>
    {
        flag.WaitOne();
        Console.WriteLine("Work Item 1 Executed");
    });
    ThreadPool.QueueUserWorkItem(s =>
    {
        flag.WaitOne();
        Console.WriteLine("Work Item 2 Executed");
    });
    Thread.Sleep(1000);
    flag.Set();
    flag.Close();
    Console.WriteLine("Finished");
}
Run Code Online (Sandbox Code Playgroud)

当然,正如多线程代码的情况一样,成功的测试并不能证明这实际上是线程安全的.如果我Close之前提出的话,测试也会成功Set,即使文档明确指出在a之后尝试做任何事情Close都会导致未定义的行为.

我的问题是,当我调用该ManualResetEvent.Set方法时,是否保证将控制权返回给调用者之前发出所有等待线程的信号?换句话说,假设我能够保证不会再进一步​​调用,在这里关闭句柄是否安全,或者在某些情况下这个代码可能会阻止一些服务员发出信号或导致一个?WaitOneObjectDisposedException

该文档仅表示Set将其置于"信号状态" - 它似乎没有任何关于服务员何时会获得该信号的声明,所以我想确定.

.net multithreading manualresetevent

11
推荐指数
2
解决办法
3209
查看次数

关于使用ManualResetEvent的用法c#?

我不熟悉ManualResetEvent的用法?

它与线程有关吗?它做什么以及何时使用?

在这里我得到了一个使用ManualResetEvent的代码,但我只是不明白它的作用?

这是代码

public class Doc : SomeInterfaceFromTheDll
{
  private readonly IVersion version; // An interface from the DLL.
  private readonly ManualResetEvent _complete = new ManualResetEvent(false);

  private bool downloadSuccessful;

  // ...

  public bool Download()
  {
    this.version.DownloadFile(this);
    // Wait for the event to be signalled...
    _complete.WaitOne();
    return this.downloadSuccessful;
  }

  public void Completed(short reason)
  {
    Trace.WriteLine(string.Format("Notify.Completed({0})", reason));
    this.downloadSuccessful = reason == 0;
    // Signal that the download is complete
    _complete.Set();
  }

  // ...
} 
Run Code Online (Sandbox Code Playgroud)

的意义是什么 _complete.WaitOne(); & _complete.Set(); ?

任何人都可以给我一些小样本代码,其中包含ManualResetEvent类的用法.

寻找好的讨论和使用ManualResetEvent?谢谢

c# manualresetevent

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

在ManualResetEvent或Thread.Sleep()之间做出选择

我不确定采用哪种策略......我专注于我的操作完成,但我也想将性能问题保持在最低限度......有一种名为Execute()的方法必须等待(同步运行)直到操作完成.此操作发生在另一个线程上.有两种方法可以实现同样的事情......

通过使用ManualResetEvent

void Execute()
{
    taskHandle = new ManualResetEvent(false);
    .
    .
    //delegate task to another thread
    .
    .
    taskHandle.WaitOne();
}
Run Code Online (Sandbox Code Playgroud)

要么

通过使用简单的while构造

void Execute()
{
    .
    .
    //delegate task to another thread
    .
    .
    while (!JobCompleted)
        Thread.Sleep(1000);
}
Run Code Online (Sandbox Code Playgroud)

我应采用两种方法中的哪一种......为什么?

编辑:

Q2.如果我在构造时只是空了怎么办?有什么不同...?

while(!JobCompleted);
Run Code Online (Sandbox Code Playgroud)

编辑:(之前我收集过的东西)

http://www.yoda.arachsys.com/csharp/threads/waithandles.shtml - 这篇文章说手动复制比较慢,因为它们离开了托管代码并重新进入......

c# multithreading sleep manualresetevent

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

退出/取消跨线程循环的技术:bool,ManualResetEvent或CancellationToken

我正在编写一个包含几个线程的程序,每个程序都有一个while循环,直到用户指定它应该停止.我想到了退出循环的几种方法,以及随后的线程,并在下面概述了这些方法.

问题

  1. 每个都有利弊吗?
  2. 是否有使用一个而不是另一个的情况?
  3. 我听说过一些人说他们更喜欢CancellationTokens退出线程.对于其他两种方法,这种方法有什么吸引力呢?

以下是方法.

bool方法

最初,我已经声明了一个bool并且刚刚声明循环运行直到用户将bool设置为false : while(running) { Thread.Sleep(10); /*do work*/ }. 然后我思索是否完全是线程安全的.如果编译器进行了一些优化并将bool移动到寄存器,该怎么办?在这种情况下,线程会看到bool的不同值.因此,我使用volatile关键字标记bool 以避免编译器优化.

ManualResetEvent方法

我的下一个方法是创建一个ManualResetEvent,并且只是说,当WaitOne()为false时bool运行:while(!mre.WaitOne(10)) {/*do work*/}.这将阻塞10ms,然后一遍又一遍地运行循环,直到我们这样做mre.Set()并且循环退出.

CancellationToken方法

我还没有尝试过这种方法,但是我读了几个人们喜欢用这种方式取消线程的地方.它显然是线程安全的.可以定义一个CancellationTokenSource,调用它cts,然后传递cts.Token给新线程运行的方法,并使用if语句检查是否已请求取消:while(!token.IsCancellationRequested) { Thread.Sleep(10); /*do work*/ }

更新1:

我发现了一篇类似的帖子,得出的结论是该MRE方法明显慢于该CancellationToken方法.有关完整信息,请参阅此处:停止线程,ManualResetEvent,volatile boolean或cancellationToken

更新2:

当谈到将这种bool方法与其他两种方法进行比较时,Eric Lippert在这里有一个很好的答案:AutoResetEvent vs. boolean来阻止一个线程

更新3:

我找到了另一条相关的信息.取消取消后,取消权限无法重置.因此,当您只想暂时取消循环,以后再次启动它时,它并不理想.为此,MRE可能会更好(因为您可以根据自己的内容设置和重置).

c# multithreading manualresetevent cancellation cancellation-token

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

锁定manualResetEvent时出现死锁

我遇到了在锁定manualResetEvent实例时导致的死锁.我无法弄清楚如何解决它.我将不胜感激任何帮助.

我在不同线程执行的类中有2个方法:

private ManualResetEvent _event = new ManualResetEvent (true);

private void process(){
  ...
  lock(_event){
    _event.WaitOne();
    ...
  }
}

internal void Stop(){
  _event.Reset();
  lock(_event){
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

第一个线程启动了锁,并在_event.WaitOne()中被阻止;

socond线程执行了_event.Reset()行; 并在尝试执行锁定(_event)时被阻止.

我认为当在WaitOne上阻塞线程1时,应该释放锁.我想我错了.我不知道如何解决它.顺便说一句 - 我添加了锁,因为锁块中的代码应该在两个线程中同步.

再次感谢,并为长篇文章感到抱歉.

.net deadlock manualresetevent

7
推荐指数
2
解决办法
2189
查看次数

WinForms RichTextBox:如何异步重新格式化,而不触发TextChanged事件

这是对WinForms RichTextBox的跟进
:如何在TextChanged上执行格式化?

我有一个带有RichTextBox的Winforms应用程序,该应用程序会自动突出显示所述框的内容.因为大型文档的格式化需要很长时间,10秒或更长时间,我已经设置了BackgroundWorker来重新格式化RichTextBox.它遍历文本并执行一系列这些:

rtb.Select(start, length);
rtb.SelectionColor = color;
Run Code Online (Sandbox Code Playgroud)

在这样做的同时,UI仍然保持响应.

BackgroundWorker从TextChanged事件开始.像这样:

private ManualResetEvent wantFormat = new ManualResetEvent(false);
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
    xpathDoc = null;
    nav = null;
    _lastChangeInText = System.DateTime.Now;
    if (this.richTextBox1.Text.Length == 0) return;
    wantFormat.Set();
}
Run Code Online (Sandbox Code Playgroud)

后台worker方法如下所示:

private void DoBackgroundColorizing(object sender, DoWorkEventArgs e)
{
    do
    {
        wantFormat.WaitOne();
        wantFormat.Reset();

        while (moreToRead())
        {
            rtb.Invoke(new Action<int,int,Color>(this.SetTextColor,
                      new object[] { start, length, color} ) ;
        }                

    } while (true);
}

private void SetTextColor(int start, int length, System.Drawing.Color color) …
Run Code Online (Sandbox Code Playgroud)

.net multithreading richtextbox manualresetevent winforms

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