感谢您查看我的问题:我有一个(非gui线程)BlockingCollection
,我一直认为它是FIFO(先进先出),但我现在意识到它不是
我在dotnetfiddle粘贴了一个代码示例,但因为它没有运行多线程,所以你看不到发生的错误,但你可以看到代码
确定。那我想要什么?我想在Visual Studio Express 2013 C# Winforms
中创建一个第二个线程(非GUI),它就像一个工作室,可以按照它们发送的顺序执行它所传递的内容。
我选择了这样的结构:
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)只运行为一个额外的线程和c)第二个线程始终在运行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();
}
}
}
答案 0 :(得分:0)
好吧我差点就在那里只是确保消费者在生产者之前开始(即在构造函数中),仍然不是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