score:1
Ok thanks to Murph's advice I have found my solution, here it is if anyone wants a reference,
In my service i have
private ReversalSender _revSender;
private Thread _revSenderThread;
public EftcObReversalService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
_revSender = new ReversalSender();
_revSenderThread = new Thread(new ThreadStart(_revSender.Run));
_revSenderThread.Start();
var timer = new System.Timers.Timer(5000);
timer.Elapsed += new ElapsedEventHandler(TimerElapsed);
timer.Start();
}
void TimerElapsed(object sender, ElapsedEventArgs e)
{
_revSender.Signal();
}
protected override void OnStop()
{
_revSender.Stop();
_revSenderThread.Join(60000);
}
Now to make sure that we have no concurrency issues accesing the DB the ReversalSender has a ManualResetEvent
public class ReversalSender
{
private bool _running = true;
private ManualResetEvent _reset = new ManualResetEvent(false);
public void Run()
{
while (_running)
{
_reset.WaitOne();
//We now need to grab all the waiting reversals
ReversalsDataContext db = new ReversalsDataContext();
var reversals = db.FiReversals.Where(r => r.Status == Reversal.ReversalStatus.WAITING_TO_SEND);
if (reversals.Any())
{
foreach (var rev in reversals)
{
if (_running)
SendReversal(rev);
}
}
db.SubmitChanges();
}
}
private void SendReversal(FiReversal rev)
{
.....
}
public void Signal()
{
_reset.Set();
}
public void Stop()
{
_running = false;
}
}
score:0
Just a hunch, but I think you are on the right track. Try removing the first call to db.SaveChanges().
if (reversals.Any())
{
foreach (var rev in reversals)
{
MarkReversal(rev);
}
//We now need to send the reversal
foreach (var rev in reversals)
{
SendReversal(rev);
}
db.SubmitChanges();
}
EDIT: Could you not do this:
if (reversals.Any())
{
foreach (var rev in reversals)
{
MarkReversal(rev);
SendReversal(rev);
}
db.SubmitChanges();
}
Do the two calls in the same context for each object.
score:2
I was about to suggest that the simplest solution would be to requery for "pending"... but of course that doesn't actually solve the problem if the process is going to overrun.
There are a couple of options that I can see quickly:
- Change the logic so that you can only run one instance of the processing loop at a time - basically if you're already processing you can't start so skip or reschedule.
- In addition to changing the state you also need to add a batch number so that you can requery after the first save but restrict that query to items pending for a particular batch number - I've done this in the past and had it work reasonably well providing the error handling was smart enough to be able to tidy up afterward if something went strange.
Source: stackoverflow.com
Related Articles
- Problem in c# windows service using linq
- How can I store Linq to Sql objects in session using Windows Azure Cache Service (Preview)
- Convert string[] to int[] in one line of code using LINQ
- Problem with LINQ to Entities query using Sum on child object property
- Left outer join using LINQ -- understanding the code
- How to reuse a linq expression for 'Where' when using multiple source tables
- Avoiding code repetition when using LINQ
- Using LINQ to delete an element from a ObservableCollection Source
- LINQ Source Code Available
- What are the alternatives to using Expand in a LINQ to ADO.net Data Service Query?
- Using DefaultIfEmpty in Linq - problem substituting a null value for a default value
- Solution to travelling salesman problem using nearest neighbour algorithm in one LINQ query?
- Problem with adding record using LINQ to SQL
- How can I write the following code more elegantly using LINQ query syntax?
- How can I code an outer join using LINQ and EF6?
- HtmlAgilityPack using Linq for windows phone 8.1 platform
- C# .Net 3.5 Code to replace a file extension using LINQ
- Trying to understand LINQ code using c#
- Problem using string.IsnullorEmpty in linq query
- Retrieve bool result by using LinQ code
- Problem with simple join by multiple columns in two tables using linq
- Close all MDI child windows using Linq
- creating Linq to sqlite dbml from DbLinq source code
- read icollection data using LINQ in C# code
- How do I add a new element to the existing XML file on Windows Phone 7 using LINQ to XML?
- How to show multiple fields in combobox using linq in C# Windows form?
- Linq sub query when using a repository pattern with EF code first
- Linq to sql as object data source - designer problem with partial classes
- Convert SQL - LINQ - Problem with using both Min/Max
- Using LINQ query result for data source for GridControl c#
- Linq Returning Sum of 2 separate columns in same query
- How to write an "OR" within a Linq to Sql .Where()
- Wrong output LINQ Sum
- Are there any production-ready LINQ implementations for javascript?
- Linq query to remove all data containing a specific matching number
- Refactoring LINQ to Query Expressions
- Trying to update a DataRow in C# with LINQ
- Linq orderby and distinct
- Linq to Entities Query -
- How to calculate number of leap years between two years in C#
- Why is ToLookup() dependent on load options in Linq2Sql?
- Linq XML NullReference Exception on reading list of elements
- How to return two specific columns from database using LINQ?
- Accessing the base list of a Linq query
- LINQ Join with Multiple Conditions in On Clause
- How can I filter a DataSource before applying it to a ListView
- How to LINQ query with variable where and select?
- Grab Id from asp.net and use in C# code
- How to send list of linq results to ajax c#?
- LINQ: Select all from each group except the first item