gpt4 book ai didi

c# - 使用 C# 的暂停事件处理

转载 作者:太空宇宙 更新时间:2023-11-03 13:02:03 27 4
gpt4 key购买 nike

我有 2 个类:

public class A
{
private const int MAXCOUNTER = 100500;
private Thread m_thrd;
public event Action<string> ItemStarted;
public event Action<string> ItemFinished;

private void OnItemStarted(string name)
{
if (ItemStarted != null) ItemStarted(name);
}

private void OnItemFinished(string name)
{
if (ItemFinished != null) ItemFinished(name);
}

public A()
{
m_thrd = new Thread(this.Run);
m_thrd.Start();
}

private void Run()
{
for (int i = 0; i < MAXCOUNTER; i++)
{
OnItemStarted(i.ToString());
// some long term operations
OnItemFinished(i.ToString());
}
}
}

public class B
{
private Thread m_thrd;
private Queue<string> m_data;
public B()
{
m_thrd = new Thread(this.ProcessData);
m_thrd.Start();
}

public void ItemStartedHandler(string str)
{
m_data.Enqueue(str);
}

public void ItemFinishedHandler(string str)
{
if (m_data.Dequeue() != str)
throw new Exception("dequeued element is not the same as finish one!");
}

private void ProcessData()
{
lock (m_data)
{
while (m_data.Count != 0)
{
var item = m_data.Peek();
//make some long term operations on the item
}
}
}
}

我们还有其他地方的代码

A a = new A();
B b = new B();
a.ItemStarted += b.ItemStartedHandler;
a.ItemFinished += b.ItemFinishedHandler;
  • 那么,如果在 ProcessData() 仍在工作时引发 ItemFinished,会发生什么?
  • 我是否应该使用 AutoResetEvent 之类的东西让类 A 等待类 B 完成 ProcessData?<
  • 是否有必要在ProcessData中使用lock
  • 是否可以使用 m_thrd = new Thread(this.ProcessData); 调用类 B 的线程?这里的事情让我感到困惑 - ProcessData 不会在引发任何 ItemStarted 事件之前完成(它不会导致线程在 B 中的情况吗? > 第一次生成 ItemStarted 时已经完成了)?

最佳答案

您的代码有点困惑。

如果在 ProcessData() 完成之前引发了 ItemFinished,那么您的第一个问题是竞争条件。

不用担心使用 AutoResetEvent。简单的事情是锁定对 m_data 的每次访问。所以这导致了下一个问题 - 是的,锁是必要的,而且到处都是必要的。

但是您的最后一点是最重要的。您需要将每个构造函数更改为 .Start() 方法,以便在开始之前留出时间进行连接。

但是,即便如此,您仍然面临巨大的竞争条件。

要完成这项工作,您应该执行以下操作。 NuGet“Rx-Main”将 Microsoft 的 Reactive Framework 添加到您的代码中。然后这样做:

var scheduler1 = new EventLoopScheduler();
var scheduler2 = new EventLoopScheduler();

Observable
.Range(0, 100500)
.ObserveOn(scheduler1)
.Do(x => { /* some long term operations */ })
.ObserveOn(scheduler2)
.Subscribe(x =>
{
//make some long term operations on the item
});

工作完成。

关于c# - 使用 C# 的暂停事件处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32022766/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com