我在C#中编写代码以在进程中创建一个线程,并在另一个进程中每2分钟调用一个Jquery ajax(使用JQuery SetInterval
)来创建一个相同的线程。
但是我想,如果线程池中已经存在一个线程,那么创建线程的新请求什么都不做。
我该怎么做?
更新 -
我做工作发布工作。当用户在Job Site
上发布作业时。我需要在一段时间(约2分钟)之后获得工作状态(工作岗位或不工作岗位),所以为此我在服务器端代码和睡眠线程上创建一个线程2分钟和return false
。同时,在客户端我设置一个设置时间间隔2分钟并调用ajax函数来创建相同的线程。
我的代码 -
var List = ["JobTitle", "JobDescription", "JobId"];
var JobDetails = JSON.stringify({ list: List });
$.ajax({
type: "POST",
url: "JobManagement.aspx/JobPost",
data: JobDetails,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
if (response.d.indexOf("Error") != -1) {
alert(response.d);
}
else if (response.d.indexOf("Job Queued up") != -1) {
var TransactionId = response.d.split(':')[1];
var GetJobStatusInterval = setInterval(function () {
$.ajax({
type: "POST",
url: "JobManagement.aspx/GetJobStatusMethod",
data: '{TransactionId: ' + "'" + TransactionId + "'" + '}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
clearInterval(GetJobStatusInterval);
},
failure: function (response) { }
});
}, 20000);
}
},
failure: function (response) { }
});
C#代码 -
[System.Web.Services.WebMethod()]
public static string JobPost(List<string> list)
{
try
{
string JobTitle = list[1];
string JobDescription = HttpUtility.HtmlEncode(list[2]);
string JobId = list[2];
string TransactionDID = "";
JobManagement oJobManagement = new JobManagement();
string JobData = "<JobTitle>" + JobTitle + "</JobTitle><JobDescription>" + JobDescription + "</JobDescription><JobId>" + JobId + "</JobId>";
XmlDocument soapEnvelopeXml = new XmlDocument();
//-- Creating web request with soap action
HttpWebRequest Soapreq = (HttpWebRequest)WebRequest.Create("http://dpi.careerbuilder.com/WebServices/RealTimeJobPost.asmx");
Soapreq.Headers.Add("SOAPAction", "http://dpi.careerbuilder.com/WebServices/RealTimeJobPost/ProcessJob");
Soapreq.ContentType = "text/xml; charset=utf-8";
Soapreq.Accept = "text/xml";
Soapreq.Method = "POST";
soapEnvelopeXml.LoadXml("<?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><ProcessJob xmlns='http://dpi.careerbuilder.com/WebServices/RealTimeJobPost'><Job>" + JobData + "</Job></xmlJob></ProcessJob></soap:Body></soap:Envelope>");
//-- request to the server
using (Stream stream = Soapreq.GetRequestStream())
{
using (StreamWriter stmw = new StreamWriter(stream))
{
stmw.Write(soapEnvelopeXml.InnerXml.ToString());
}
}
// -- Getting response to the server
using (WebResponse response = Soapreq.GetResponse())
{
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
string soapResult = rd.ReadToEnd();
Console.WriteLine(soapResult);
TransactionDID = soapResult.ToString().Substring(soapResult.LastIndexOf("<TransactionDID>"));
TransactionDID = TransactionDID.Substring(TransactionDID.IndexOf("<TransactionDID>"), TransactionDID.IndexOf("</TransactionDID>")).Split('>')[1];
}
}
string CurrentJobStatus = "";
CurrentJobStatus = oJobManagement.GetCBJobStatus(TransactionDID);
if (CurrentJobStatus == "Job Queued up")
{
string objJobStatus = TransactionDID + ":" + oJobManagement.oUser.ID.ToString() + ":" + oJobManagement.oUser.Organisation_ID.ToString();
System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(oJobManagement.GetJobStatusForCB), (object)objJobStatus);
return "";
}
return "";
}
catch {
return "";
}
}
private string GetCBJobStatus(string TransactionId)
{
try
{
string PostJobStatus = "";
JobManagement oJobManagement = new JobManagement();
HttpWebRequest JobStatusreq = (HttpWebRequest)WebRequest.Create("http://dpi.careerbuilder.com/webservices/RealTimeJobStatus.asmx/GetJobPostStatus?sTGDID=" + TransactionId);
JobStatusreq.Method = "GET";
using (WebResponse Statusresponse = JobStatusreq.GetResponse())
{
using (StreamReader rd = new StreamReader(Statusresponse.GetResponseStream()))
{
string JobStatus = rd.ReadToEnd();
// - Post job status
PostJobStatus = JobStatus.ToString().Substring(JobStatus.LastIndexOf("<PostStatus>"));
PostJobStatus = PostJobStatus.Substring(PostJobStatus.IndexOf("<PostStatus>"), PostJobStatus.IndexOf("</PostStatus>")).Split('>')[1];
}
}
if (PostJobStatus == "Success")
{
return "Job Posted Successfully";
}
else if (PostJobStatus == "Queued")
{
return "Job Queued up";
}
return "";
}
catch (Exception ex)
{
return "";
}
}
C#函数For Thread -
// -- Make thread
private void GetJobStatusForCB(object objJobStatus)
{
try
{
System.Threading.Thread.Sleep(20000);
string TransactionDID = objJobStatus.ToString().Split(':')[0];
string JobStatus = "";
JobManagement oJobManagement = new JobManagement();
JobStatus = oJobManagement.GetCBJobStatus(TransactionDID);
if (JobStatus == "Job Queued up")
{
System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(oJobManagement.GetJobStatusForCB), (object)objJobStatus);
}
}
catch (Exception ex)
{
}
}
调用设置间隔的Web方法 -
[System.Web.Services.WebMethod()]
public static string GetJobStatusMethod(string TransactionId)
{
try
{
string JobStatusCB = "";
JobManagement oJobManagement = new JobManagement();
oJobManagement.FillUserobj();
JobStatusCB = oJobManagement.GetCBJobStatus(TransactionId);
if (JobStatusCB == "Job Queued up")
{
// -- I want to check here if a thread is already running "Do Nothing"
// -- if "A Thread is already running" return false;
string objJobStatus = TransactionId + ":" + oJobManagement.oUser.ID.ToString() + ":" + oJobManagement.oUser.Organisation_ID.ToString();
System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(oJobManagement.GetJobStatusForCB), (object)objJobStatus);
}
}
catch (Exception ex)
{
return "";
}
return "";
}
在上面的代码中,当用户点击发布作业时,主jquery ajax
会运行。我使用JobPost
网络方法获得我的工作的第一个状态,如果我获得Job Queued up
状态我使用GetJobStatusForCB
函数调用线程获取工作状态。进入此函数sleep
当前进程2分钟和return false
,在客户端获取作业状态并设置客户端SetInterval
为everv 2分钟。在此间隔中,我调用不同的Jquery ajax
来获取作业状态。在这个ajax我调用web方法GetJobStatusMethod
。在Web方法中首先检查作业状态,如果得到Job Queued up
,则调用另一个线程获取状态。在这个词干我的问题发生 - 因为如果一个线程已经运行获取作业状态我不需要创建另一个线程。
我不想更改设置时间间隔的Time
。
所以,我想你们都明白我的真正问题。谢谢你的帮助。
答案 0 :(得分:2)
您可以使用这样的模式来确保如果在新的线程池线程中启动此特定方法,则如果先前的实例已在运行,则它将不执行任何操作。
class Foo
{
//make static if this is called from different instances and should still
//be synchronized
private int isRunning = 0;
public void DoStuff()
{
if (Interlocked.Exchange(ref isRunning, 1) == 0)
{
try
{
DoRealStuff();
}
finally
{
Interlocked.Exchange(ref isRunning, 0);
}
}
}
}