1

私の質問を見てくれてありがとう: 私BlockingCollectionは常に FIFO (先入れ先出し) であると想定していた (GUI 以外のスレッド) を持っていますが、そうではないことに気付きました。

コードの例をdotnetfiddleに貼り付けましたが、マルチスレッドを実行しないため、エラーが発生していることはわかりませんが、コードを見ることができます

わかった。それで、私は何が欲しかったのですか?2 番目のスレッド (非 GUI) を作成したかったのVisual Studio Express 2013 C# Winformsですが、それは、送信された順序で渡されたものを実行する作業場のようなものでした。

次のような構造を選択しました。

nofQDo
|_addAction(|)
            |
            +-> static BlockingCollection foreach
                                          |
                                          +-> QDo.run(|)
                                                      |
                                                      +> QDoType.action(//code//)

この奇妙な配置の理由は、最大 20 個または 30 個typesのキュー オブジェクト (私はこれらをすべて と呼びますQDoType_something) が必要であり、レイアウトには満足していますが、呼び出すとエンジンが動作しませんでした。

QDoType_test gra = new QDoType_test("hey0");
nofQDo.addAction(gra);

QDoType_test grb = new QDoType_test("hey1");
nofQDo.addAction(grb);

QDoType_test grc = new QDoType_test("hey2");
nofQDo.addAction(grc);

 QDoType_test grd = new QDoType_test("hey3");
 nofQDo.addAction(grd);

 QDoType_test gre = new QDoType_test("hey4");
 nofQDo.addAction(gre);

 QDoType_test grf = new QDoType_test("hey5");
 nofQDo.addAction(grf);

私は得る

00009::hey0
00009::hey1
00009::hey5
00009::hey3
00009::hey2
00009::hey4

また

00009::hey1
00009::hey0
00009::hey3
00009::hey2
00009::hey4
00009::hey5

したがって、明らかに " FIFO" ではなく、これは憂慮すべきことです.. 私BlockingCollectionが a)not guiスレッド b) 1 つの余分なスレッドとしてのみ実行されていること、および c) この 2 番目のスレッドが常に実行されていることFIFO(先入れ先出し) を確実にする方法はありますか? ?)

要求されたとおり: 適切なコードは次のとおりです。

=QDoType_test.cs=

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QTest
{
    class QDoType_test : QDoType
    {
        String szout = "";
        private string ThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString("00000");
        public QDoType_test(String sent)
        {
            szout = sent;
        }
        public override void action()
        {
            System.Threading.Thread.Sleep(100);
            Console.WriteLine(ThreadId + "::" + szout);
        }
    }
}

=nofQDo.cs=

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace QTest
{
    class nofQDo
    {
        static BlockingCollection<QDo> queue = new BlockingCollection<QDo>(new ConcurrentQueue<QDo>()); //<--new ConcurrentQueue<QDo>() makes it FIFO

        public static void addAction(QDoType action)
        {
            QDo me = new QDo(action);
            queue.Add(me);
            Task.Factory.StartNew(() =>
            {
                foreach (QDo doThis in queue.GetConsumingEnumerable())
                {
                    doThis.run();
                }
            });
        }
    }
}

=QDoType.cs=

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QTest
{
    /// <summary>
    /// This is a Parent Class for QDoType_whatever they are non 
    /// communicative and most exist to run db calls
    /// </summary>
    public abstract class QDoType
    {
        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
         * this is a parent class not meant to ever be instaciated   *
        \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

        public string uniqueid = "";
        public Action callback;

        public abstract void action();

        /// <summary>
        /// kept for the fact you might want 
        /// to debug where it went in the Queue
        /// </summary>
        /// <param name="uid"></param>
        public void setUniqueId(string uid)
        {
            uniqueid = uid;
        }
    }
}

=QDo.cs=

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QTest
{
    class QDo
    {
        /***********
         * 
         * This class is the <T> umbrella for a real type that runs inside it
         * basically all this does in "run()" the QDoType;
         */
        public const bool DELETE_MODE = true;

        QDoType iam;

        public QDo(QDoType action)
        {
            DateTime dt = DateTime.Now;
            iam = action;
        }

        public void run()
        {
            iam.action();

            if (iam.callback != null) iam.callback();
        }
    }
}
4

1 に答える 1

1

わかりました私はほとんどそこにいました.コンシューマーがプロデューサーの前に(つまり、コンストラクターで)開始されたことを確認するだけでしたが、これが機能する理由を100%確信していません(しかし、間違いなく機能します!100%保証します!)それは単一でテストされていますユニットも走る。

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace QTest
{
    class nofQDo
    {
        static BlockingCollection<QDo> queue = new BlockingCollection<QDo>(new ConcurrentQueue<QDo>()); //<--new ConcurrentQueue<QDo>() makes it FIFO

        static nofQDo()
        {
            Task.Factory.StartNew(() =>
            {
                foreach (QDo doThis in queue.GetConsumingEnumerable())
                {
                    doThis.run();
                }
            });
        }

        public static void addAction(QDoType action)
        {
            QDo me = new QDo(action);
            queue.Add(me);
        }
    }
}

だから今

QDoType_test gra = new QDoType_test("hey0"); nofQDo.addAction(gra);

QDoType_test grb = new QDoType_test("hey1"); nofQDo.addAction(grb);

QDoType_test grc = new QDoType_test("hey2"); nofQDo.addAction(grc);

QDoType_test grd = new QDoType_test("hey3");  nofQDo.addAction(grd);

QDoType_test gre = new QDoType_test("hey4");  nofQDo.addAction(gre);

QDoType_test grf = new QDoType_test("hey5");  nofQDo.addAction(grf);

生産する

00009::hey0
00009::hey1
00009::hey2
00009::hey3
00009::hey4
00009::hey5
于 2014-07-24T08:57:09.343 に答える