ThreadPool的代码帮助

时间:2014-05-01 14:57:28

标签: c# multithreading

创建了一个实现ThreadPool的类。代码如下:

公共密封类PyeThreadPool:

  IDisposable
{
    private readonly object _lock = new object();
    private readonly int _minThreadCount;
    private readonly int _maxThreadCount;
    private readonly Queue<Action> _queue = new Queue<Action>();
    private int _totalThreadCount;
    private int _waitingThreadCount;
    private bool _disposed;

    public PyeThreadPool(int minThreadCount, int maxThreadCount)
    {
        if (minThreadCount < 0)
            throw new ArgumentOutOfRangeException("minThreadCount");

        if (maxThreadCount < 1 || maxThreadCount < minThreadCount)
            throw new ArgumentOutOfRangeException("maxThreadCount");

        _minThreadCount = minThreadCount;
        _maxThreadCount = maxThreadCount;


    }
    public void Dispose()
    {
        lock (_lock)
        {
            _disposed = true;

            // if there are thread waiting, they should stop waiting.
            if (_waitingThreadCount > 0)
                Monitor.PulseAll(_lock);
        }
    }

    /// <summary>
    /// Executes an action in a parallel thread. 
    /// </summary>
    public void RunParallel(Action action)
    {


            if (action == null)
                throw new ArgumentNullException("action");

            lock (_lock)
            {
                if (_disposed)
                    throw new ObjectDisposedException(GetType().FullName);

                bool queued = false;
                if (_waitingThreadCount == 0)
                {
                    if (_totalThreadCount < _maxThreadCount)
                    {
                        _totalThreadCount++;

                        var thread = new Thread(_ThreadRun);
                        thread.Name = "Worker Thread";
                        thread.Start(action);
                        queued = true;
                    }
                }

                if (!queued)
                {
                    _queue.Enqueue(action);
                    Monitor.Pulse(_lock);
                }
            }

    }
    private void _ThreadRun(object firstAction)
    {
        Action action = (Action)firstAction;
        firstAction = null;
        // we always start a new thread with an action, so we get it immediately.
        // but, as we don't know what that action really holds in memory, we set
        // the initial action to null, so after it finishes and a new action is get,
        // we will let the GC collect it.

        while (true)
        {
            action();

            lock (_lock)
            {
                if (_queue.Count == 0)
                {
                    // we started waiting, so new threads don't need to be created.
                    _waitingThreadCount++;


                    while (_queue.Count == 0)
                    {

                        if (_disposed)
                            return;


                        if (_totalThreadCount > _minThreadCount)
                        {
                            _totalThreadCount--;
                            _waitingThreadCount--;
                            return;
                        }


                        action = null;
                        Monitor.Wait(_lock);
                    }

                    // we finished waiting.
                    _waitingThreadCount--;
                }

                action = _queue.Dequeue();
                // we just get a new action, and we will release the lock and return
                // to the while, where the action will be executed.
            }
        }
    }
}

我试过使用它,测试代码如下:

    PyeThreadPool MyPool;

    int x = 1;

    protected void Page_Load(object sender, EventArgs e)

    {
        MyPool = new PyeThreadPool(4, 6);

    }

    void showMessage(string message)

    {

        TxtMessage.Text = message;

    }


    protected void BtnStartThread_Click(object sender, EventArgs e)

    {

        x++;
        int arg = x;
        MyPool.RunParallel(() =>
        {
            showMessage(arg.ToString());
        });

     }

问题是:

(1)当我在调试或释放模式下执行此操作时,我没有在文本框中看到结果,另一方面,当我单步执行时,我看到了结果。我在这里缺少什么,为什么我看不到输出。

(2)RunParallel方法只显示一个线程,即使我已将maxcount设置为大于1.是否缺少任何代码逻辑或是因为测试应用程序很简单?

谢谢!

2 个答案:

答案 0 :(得分:1)

您应该查看SmartThreadPool库。它是ThreadPool的最佳替代品之一。

其功能(从源链接复制)

智能线程池是用C#编写的线程池。该实现首先基于Stephan Toub的线程池以及一些额外的功能,但现在,它远远超出原始版本。以下是线程池功能的列表:

  • 线程数根据池中线程的工作负载动态更改。 工作项可以返回值。
  • 如果尚未执行工作项,则可以取消该工作项。
  • 执行工作项(限制)时使用调用者线程的上下文。
  • 使用最少数量的Win32事件句柄,因此应用程序的句柄数不会爆炸。
  • 来电者可以等待多个或所有工作项完成。
  • 工作项可以有PostExecute回调,工作项完成后会立即调用。
  • 工作项目附带的状态对象可以自动处理。
  • 将工作项例外发送回来电。
  • 工作项目具有优先权。
  • 工作项目组。
  • 调用者可以暂停线程池和工作项组的启动。
  • 主题优先。
  • 线程有初始化和终止事件。
  • 支持(限制)WinCE平台。
  • 支持Action和Func泛型方法。
  • 支持Silverlight。
  • 支持Mono。
  • 性能计数器(Windows和内部)。
  • 工作项超时(被动)。
  • Threads ApartmentState
  • 主题IsBakcground
  • 主题名称模板
  • 支持(限制)Windows Phone
  • 线程MaxStackSize

答案 1 :(得分:0)

问题是您正在尝试从后台线程更新UI控件。不允许。

您需要在ShowMessage函数中执行BeginInvoke或Invoke。