TECHNOLOGIES
FORUMS
JOBS
BOOKS
EVENTS
INTERVIEWS
Live
MORE
LEARN
Training
CAREER
MEMBERS
VIDEOS
NEWS
BLOGS
Sign Up
Login
No unread comment.
View All Comments
No unread message.
View All Messages
No unread notification.
View All Notifications
Answers
Post
An Article
A Blog
A News
A Video
An EBook
An Interview Question
Ask Question
Forums
Monthly Leaders
Forum guidelines
David Chen
NA
1
2k
SQL Deadlock, Task Factory Treading Problem
Aug 22 2012 7:52 PM
Hi all C# gurus I need advice on Deadlock
I have a code structure for Window Service, multithreading, task factory like
public partial class rs : ServiceBase
{
private Queue jobQueue = Queue.Synchronized(new Queue());
private Queue DatafeedQueue = Queue.Synchronized(new Queue());
private Dictionary<...> ScheduleJobs = new Dictionary<...>();
private AutoResetEvent _BlockThreadTaskScheduler = new AutoResetEvent(true);
private AutoResetEvent _BlockThreadDatafeedSourceTaskScheduler = new AutoResetEvent(false);
private LimitedConcurrencyLevelTaskScheduler _TaskScheduler;
private LimitedConcurrencyLevelTaskScheduler _DatafeedSourceTaskScheduler;
public rs()
{
InitializeComponent();
_timer = new System.Timers.Timer(POLL_INTERVAL_MINUTE * 60 * 1000);
_timer.Elapsed += new System.Timers.ElapsedEventHandler(_timer_Elapsed);
_TaskScheduler = new LimitedConcurrencyLevelTaskScheduler(2);
_DatafeedSourceTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(1);
protected void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
DatafeedQueue.Clear();
try
{
(Execute a stored procedure here)
while(xxx.Read())
{
DatafeedObj dfo = new DatafeedObj();
...
DatafeedQueue.Enqueue(dfo);
}
}
catch()...
TaskFactory DatafeedSourceFactory = new TaskFactory(_DatafeedSourceTaskScheduler);
// DatafeedQueue.Count = 3
for (int i = 0; i < DatafeedQueue.Count; i++)
{
DatafeedSourceFactory.StartNew(() => processDatafeedQueue());
}
_BlockThreadDatafeedSourceTaskScheduler.Set();
}
catch()...
}
private void processDatafeedQueue()
{
_BlockThreadDatafeedSourceTaskScheduler.WaitOne();
try
{
lock (DatafeedQueue.SyncRoot)
{
if (DatafeedQueue.Count > 0)
{
DatafeedObj dfo = ((DatafeedObj)(DatafeedQueue.Dequeue()));
#region DataFeed Type A
ScheduleJobs = (Calls a static class, static method);
jobQueue = (Calls a static class, static method turn ScheduleJobs dictionary into Queue);
var factory = new TaskFactory(_TaskScheduler);
for (int i = 0; i < jobQueue.Count; i++)
{
factory.StartNew(() => startTypeA());
}
#endregion
#region DataFeed Type B
ScheduleJobs = (Calls a static class, static method);
jobQueue = (Calls a static class, static method turn ScheduleJobs dictionary into Queue);
var factory = new TaskFactory(_TaskScheduler);
for (int i = 0; i < jobQueue.Count; i++)
{
factory.StartNew(() => startTypeB());
}
#endregion
#region DataFeed Type C
ScheduleJobs = (Calls a static class, static method);
jobQueue = (Calls a static class, static method turn ScheduleJobs dictionary into Queue);
var factory = new TaskFactory(_TaskScheduler);
for (int i = 0; i < jobQueue.Count; i++)
{
factory.StartNew(() => startTypeC());
}
#endregion
}
}
}
if (_TaskScheduler.NumberOfRemainingScheduledTasks == 0)
{
_BlockThreadDatafeedSourceTaskScheduler.Set();
}
}
void startTypeA()
{
(In this method, it creates a object from another project class which calls a WCF Service and select data and insert into local db and run stored procedures)
}
void startTypeB()
{
(Same as startTypeA but calls a different WCF and insert into the same set of tables which startTypeA also insert into then also run a same set of stored procedures)
}
void startTypeC()
{
(Same as startTypeC but calls a different WCF and into different set of tables than startTypeA and startTypeB then run different set of stored procedures)
}
...
I was able to grab all the data from all 3 set of WCF services but the problem is after Type A and Type B insert the data and both calls the same set of stored procedures a few Job Queue had Error 1205, deadlock. Then after service has stopped, I had to manually rerun the stored procedures to process those leftover.
Can anyone know how to fix the deadlock, also I use AutoResetEvent to keep a thread blocked while another thread is processing. It doesn't seem like its doing its job.
I was thinking for alternative way but I would like to keep the same logic, task factory...
My alternative way, non-tested with actual code, but I wrote a draft similar to what I needed, but I am unsure if deadlock will still exists
class Program
{
static SemaphoreSlim _sem = new SemaphoreSlim(3);
static void Main()
{
for (int i = 1; i <= 3; i++)
{
new Thread(RunThisMethod).Start(i);
}
Console.ReadLine();
}
static void RunThisMethod(Object id)
{
Console.WriteLine(id + " wants to enter");
_sem.Wait();
if (id.ToString() == "1")
{
Console.WriteLine("Start Type A");
Thread.Sleep(3000);
Console.WriteLine("End Type A");
}
else if (id.ToString() == "2")
{
Console.WriteLine("Start Type B");
Thread.Sleep(6000);
Console.WriteLine("End Type B");
}
else if (id.ToString() == "3")
{
Console.WriteLine("Start Type C");
Thread.Sleep(9000);
Console.WriteLine("End Type C");
}
_sem.Release();
}
}
Reply
Answers (
0
)
How can be able to send and receive sms in C# windows forms using SQL Server
IComparable