我更新了一個使用Supersocket連接到舊C++服務器的舊項目。使用最新版本(從0.7.0 => 0.8.0.8),我在嘗試重新連接時遇到了異常(它表示套接字在不同的線程上打開),我希望有一個將任務排入隊列的類(第一個連接和重新連接)並在一個快速的線程上運行它們。編碼任務在特定線程上運行
我見過this方法,但是當我嘗試運行創建爲有一個例外
ExecuteTask may not be called for a task which was previously queued to a different TaskScheduler.
這裏的任務是我從鏈接採取上述
public class SameThreadTaskScheduler : TaskScheduler, IDisposable
{
#region publics
public SameThreadTaskScheduler(string name)
{
scheduledTasks = new Queue<Task>();
threadName = name;
}
public override int MaximumConcurrencyLevel => 1;
public void Dispose()
{
lock (scheduledTasks)
{
quit = true;
Monitor.PulseAll(scheduledTasks);
}
}
#endregion
#region protected overrides
protected override IEnumerable<System.Threading.Tasks.Task> GetScheduledTasks()
{
lock (scheduledTasks)
{
return scheduledTasks.ToList();
}
}
protected override void QueueTask(Task task)
{
if (myThread == null)
myThread = StartThread(threadName);
if (!myThread.IsAlive)
throw new ObjectDisposedException("My thread is not alive, so this object has been disposed!");
lock (scheduledTasks)
{
scheduledTasks.Enqueue(task);
Monitor.PulseAll(scheduledTasks);
}
}
public void Queue(Task task)
{
QueueTask(task);
}
protected override bool TryExecuteTaskInline(Task task, bool task_was_previously_queued)
{
return false;
}
#endregion
private readonly Queue<System.Threading.Tasks.Task> scheduledTasks;
private Thread myThread;
private readonly string threadName;
private bool quit;
private Thread StartThread(string name)
{
var t = new Thread(MyThread) { Name = name };
using (var start = new Barrier(2))
{
t.Start(start);
ReachBarrier(start);
}
return t;
}
private void MyThread(object o)
{
Task tsk;
lock (scheduledTasks)
{
//When reaches the barrier, we know it holds the lock.
//
//So there is no Pulse call can trigger until
//this thread starts to wait for signals.
//
//It is important not to call StartThread within a lock.
//Otherwise, deadlock!
ReachBarrier(o as Barrier);
tsk = WaitAndDequeueTask();
}
for (;;)
{
if (tsk == null)
break;
TryExecuteTask(tsk);
lock (scheduledTasks)
{
tsk = WaitAndDequeueTask();
}
}
}
private Task WaitAndDequeueTask()
{
while (!scheduledTasks.Any() && !quit)
Monitor.Wait(scheduledTasks);
return quit ? null : scheduledTasks.Dequeue();
}
private static void ReachBarrier(Barrier b)
{
if (b != null)
b.SignalAndWait();
}
}
這裏是如何的類我打電話給任務
public void RegisterServers()
{
sameThreadTaskScheduler.Queue(new Task(() =>
{
...something
}));
什麼在做錯? 謝謝
嘗試在任務調度程序中使用Task.Start(TaskScheduler)或Task.Factory.StartNew,而不是使用此公共的Queue方法。 – acelent