0

我正在尝试创建某种框架来简化编写对象交互算法的过程。(一个对象——许多客户端(算法))

  • 例如,我想实现一些非常简单的工作并在循环中等待满足某些条件的算法:

    public void MakeVerySimpleJob() { }
    
    public void AsyncLoop()
    { // real algorithm can be more complex, but job is always very simple
        while (true)
        {
            MakeVerySimpleJob();
            WakeUpCondition = "As fast as u can!";
            JobComplete.Set();
            WakeUp.WaitOne();
        }
    }
    
    void main()
    {
        Thread MyThread = new Thread(AsyncLoop);
        MyThread.Start();
    
        var w = new System.Diagnostics.Stopwatch(); w.Start();
        for (int i = 0; i < 100000; i++)
        {
            // waitin for thread
            JobComplete.WaitOne();
            // ok we did it
            WakeUpCondition = null;
            WakeUp.Set();
        }
        w.Stop();
    }
    
    AutoResetEvent JobComplete = new AutoResetEvent(false);
    AutoResetEvent WakeUp = new AutoResetEvent(false);
    

    不幸的是,它消耗大约500ms100000 个简单的工作。

  • 好的多线程在我的情况下是不可接受的,但我不想强迫用户以这种方式编写算法:

    // invoke it again and again
    public void PseudoAsyncLoop()
    {
        if (CurrentState == 1) 
        {
            MakeVerySimpleJob();
            CurrentState = 2;
            return;
        }
        else is (CurrentState == some_sate)
        {
        }
    }
    
    int CurrentState = 0;
    
  • 所以我看看Enumerators。使用 Enumerators 用户可以以传统风格实现自己的算法:

    public IEnumerable<bool> PseudoAsyncLoop()
    {
        while (true)
        {
            MakeVerySimpleJob();
            WakeUpCondition = "As fast as u can!";
            yield return true;
        }
    }
    
    public string WakeUpCondition { get; private set; }
    
    void main()
    {
        var MyLoop = PseudoAsyncLoop();
        var LoopEnumerator = MyLoop.GetEnumerator();
    
        var w = new System.Diagnostics.Stopwatch(); w.Start();
        for(int i = 0; i < 100000; i ++)
        {
            LoopEnumerator.MoveNext();
            // ok we did it
            WakeUpCondition = null;
        }
        w.Stop();
    }
    

    现在它需要大约3ms,太好了。但我认为这一切都有问题......

我的问题是:

  • 我的方向正确吗?
  • 专业程序员如何解决这类问题?
  • 可能有一些方法可以优化多线程版本?
4

1 回答 1

1

我不完全理解你在做什么或为什么,但如果这实际上代表你的代码,那么你可以通过使用-Slim同步原语之一来加速它。没有AutoResetEventSlim,但您可以SemaphoreSlim改用:

private readonly SemaphoreSlim JobComplete = new SemaphoreSlim(0, 1);
private readonly SemaphoreSlim WakeUp = new SemaphoreSlim(0, 1);

private void AsyncLoop()
{
    while (true)
    {
        MakeVerySimpleJob();
        WakeUpCondition = "As fast as u can!";
        JobComplete.Release();
        WakeUp.Wait();
    }
}

private void main()
{
    Thread MyThread = new Thread(AsyncLoop);
    MyThread.Start();

    for (int i = 0; i < 100000; i++)
    {
        JobComplete.Wait();
        WakeUpCondition = null;
        WakeUp.Release();
    }
}

这导致我的机器上的执行速度提高了大约 5.5 倍。

于 2013-01-30T19:29:52.600 回答