【发布时间】:2014-05-30 13:46:27
【问题描述】:
场景
一个 Windows 服务每两分钟轮询一次 url 以检索某些数据。
如果自上次调用以来添加了任何数据,则检索并存储数据,否则循环继续。
问题
有时一个请求需要超过两分钟才能返回响应。
发生这种情况时,仍会发出下一个请求并查找新数据,因为上一个请求尚未返回响应
这会导致存储数据时出现重复条目。
我尝试过的
我试图通过使用像这样的布尔值来处理这个问题:
Boolean InProgress = true;
foreach (var item in Lists)
{
\\Make a request and return new data (if any)
InProgress = false;
if (InProgress = false)
{
\\Store new data
}
}
这并不能解决问题。我相信我在错误的地方使用了布尔值,但我不确定它应该在哪里。
这是发出请求并存储数据的循环
void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
Data getCredentials = new Data();
DataTable credentials = getCredentials.loadCredentials();
Boolean InProgress = true;
for (int i = 0; i < credentials.Rows.Count; i++)
{
if (credentials != null)
{
var PBranchID = (int)credentials.Rows[i]["PortalBranchID"];
var negRef = (int)credentials.Rows[i]["NegotiatorRef"];
var Username = credentials.Rows[i]["Username"].ToString();
var Password = credentials.Rows[i]["Password"].ToString();
var Domain = credentials.Rows[i]["Domain"].ToString();
var FooCompanyBaseUrl = "https://" + Domain + ".FooCompany.com/";
Data getCalls = new Data();
DataTable calls = getCalls.loadCalls(PBranchID);
//If it's not the first call
if (calls != null && calls.Rows.Count > 0)
{
//Makes a call
DateTime CreatedSince = DateTime.SpecifyKind((DateTime)calls.Rows[0]["LastSuccessOn"], DateTimeKind.Local);
string IssueListUrl = FooCompany.WebApi.V2.URLs.Issues(BaseUrl, null, CreatedSince.ToUniversalTime(), null);
FooCompany.WebApi.V2.DTO.PrevNextPagedList resultIssueList;
resultIssueList = FooCompany.WebApi.Client.Helper.Utils.Getter<Foocompany.WebApi.V2.DTO.PrevNextPagedList>(IssueListUrl, Username, Password);
InProgress = false;
if (InProgress == false)
{
if (resultIssueList.Items.Count > 0)
{
//If call returns new issues, save call
Data saveCalls = new Data();
saveCalls.saveCalls(PBranchID);
foreach (var item in resultIssueList.Items)
{
var Issue = FooCompany.WebApi.Client.Helper.Utils.Getter<FooCompany.WebApi.V2.DTO.Issue>(item, Username, Password);
string TenantSurname = Issue.Surname;
string TenantEmail = Issue.EmailAddress;
Data tenants = new Data();
int tenantPropRef = Convert.ToInt32(tenants.loadTenantPropRef(PBranchID, TenantSurname, TenantEmail));
Data Properties = new Data();
DataTable propAddress = Properties.loadPropAddress(PBranchID, tenantPropRef);
var Address1 = propAddress.Rows[0]["Address1"];
var Address2 = propAddress.Rows[0]["Address2"];
var AddressFolder = Address1 + "," + Address2;
if (!Directory.Exists("path"))
{
Directory.CreateDirectory("path");
}
string ReportPDFDestination = "path";
if (File.Exists(ReportPDFDestination))
{
File.Delete(ReportPDFDestination);
}
FooCompany.WebApi.Client.Helper.Utils.DownloadFileAuthenticated(FooCompany.WebApi.V2.URLs.IssueReport(BaseUrl, Issue.Id), Username, Password, ReportPDFDestination);
//Store data
}
IssueListUrl = resultIssueList.NextURL;
}
}
}
else
{
continue;
}
}
}
catch (Exception ex)
{
//write to log
}
}
问题
我确信有比布尔值更好的方法。
谁能建议一种不同的方法来正确处理这个问题? 谢谢。
解决方案
我最终结合了 Thomas 和 Mason 的建议。我在我的 Windows 服务的主要功能周围包裹了一个锁定语句,并在调用远程服务器的函数部分中使用了一个布尔值。 经过多次测试,没有错误。
【问题讨论】:
-
我们需要查看调用此代码的您的代码,以便给您一个良好的响应。
-
我使用线程,但我会跟踪标志中的状态,并且在标志重置为零或超过合理时间之前,我不允许它再次调用。
-
@mason 我已经添加了调用的代码
-
@dura 添加同步是否解决了您的问题?
-
您添加了实际检索数据的代码,但这并不真正相关。我们需要看看你发布的第一个代码是什么。顺便说一句,第一个块,您将布尔值设置为假,然后测试它是否为假。它总是是假的。您需要使用
==来测试是否相等。=是赋值运算符。
标签: c# service windows-services locking boolean