gpt4 book ai didi

c# - 帮助从 C# 中的单元测试进行同步

转载 作者:太空宇宙 更新时间:2023-11-03 14:20:17 25 4
gpt4 key购买 nike

我正在测试一个包装 BackgroundWorker 的类,以便在我的应用程序中执行远离 UI 线程的操作。

如果超过超时,下面的测试将失败;如果 progressEventCount 在此之前达到预期的事件数,则通过。

我的问题是关于同步的。 asyncExecutor.Progressed 从 BackgroundWorker 正在使用的线程池线程中触发,测试线程在 while 循环中读回它。

我是否正确使用锁?

    [Test]
[Timeout(1250)]
public void Execute()
{
var locker = new object();
const int numberOfEvents = 10;
const int frequencyOfEvents = 100;
var start = DateTime.Now;
int progressEventCount = 0;

IGradualOperation tester = new TestGradualOperation(numberOfEvents, frequencyOfEvents);

var asyncExecutor = new AsynchronousOperationExecutor();

asyncExecutor.Progressed += (s, e) => { lock (locker) progressEventCount++; };

asyncExecutor.Execute(tester);

while (true)
{
int count;
lock (locker)
{
count = progressEventCount;
}
if (count < numberOfEvents) continue;
Assert.Pass("Succeeded after {0} milliseconds", (DateTime.Now - start).TotalMilliseconds);
}
}


// Implementation
public class AsynchronousOperationExecutor
{
public void Execute(IGradualOperation gradualOperation)
{
var backgroundWorker = new BackgroundWorker {WorkerReportsProgress = true};

backgroundWorker.DoWork += BackgroundWorkerDoWork;
backgroundWorker.ProgressChanged += BackgroundWorkerProgressChanged;
backgroundWorker.RunWorkerAsync(gradualOperation);
}

private void BackgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
{
var myArgs = e.UserState as ProgressEventArgs;
OnProgressed(myArgs);
}

static void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
var workerThis = sender as BackgroundWorker;
var operation = e.Argument as IGradualOperation;

if (workerThis == null || operation == null) return;

operation.Progressed += (s, e1) => workerThis.ReportProgress((int)e1.Percentage, e1);

operation.Run();
}

private void OnProgressed(ProgressEventArgs e)
{
if (Progressed != null)
Progressed(this, e);
}

public event EventHandler<ProgressEventArgs> Progressed;
}


// Test Helper Class
public class TestGradualOperation : IGradualOperation
{
private readonly int _numberOfEvents;
private readonly int _frequencyMilliseconds;

public TestGradualOperation(int numberOfEvents, int frequencyMilliseconds)
{
_numberOfEvents = numberOfEvents;
_frequencyMilliseconds = frequencyMilliseconds;
}

public void Run()
{
for (int i = 0; i < _numberOfEvents; i++)
{
Thread.Sleep(_frequencyMilliseconds);
OnProgressed(new ProgressEventArgs(i, _numberOfEvents));
}
}

private void OnProgressed(ProgressEventArgs e)
{
if (Progressed != null)
Progressed(this, e);
}

public event EventHandler<ProgressEventArgs> Progressed;
}

最佳答案

我认为这次修订是一项改进,阻止了测试线程并使用 AutoResetEvent 发出信号。虽然没有赢得任何测试可读性的加分。

    [Test]
[Timeout(1250)]
public void Execute()
{
var locker = new object();
EventWaitHandle waitHandle = new AutoResetEvent(false);// <--
const int numberOfEvents = 10;
const int frequencyOfEvents = 100;
var start = DateTime.Now;
int progressEventCount = 0;

IGradualOperation tester = new TestGradualOperation(numberOfEvents, frequencyOfEvents);

var asyncExecutor = new AsynchronousOperationExecutor();

asyncExecutor.Progressed += (s, e) =>
{
lock (locker)
{
progressEventCount++;
waitHandle.Set();// <--
}
};

asyncExecutor.Execute(tester);

while (true)
{
waitHandle.WaitOne();// <--
if (progressEventCount < numberOfEvents) continue;
Assert.Pass("Succeeded after {0} milliseconds", (DateTime.Now - start).TotalMilliseconds);
}
}

关于c# - 帮助从 C# 中的单元测试进行同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5628230/

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