背景:我需要使用計劃任務來掃描數據表(1分鐘掃描一次,或者30秒一次),數據表會增加記錄,第三個數據源中的數據表與收集作爲參數做一個Thing,這個事情所需的時間無法確定(一個http請求),修改後的每個數據庫記錄狀態完成後,避免再次掃描下一次查詢時出現。IJob實現類Execute方法如何使用lock關鍵字?
public class ScanJob : IJob
{
//Simulation of the data table, the reality of his records will not increase.
public static List<Person> persions = new List<Person>
{
new Person() { Name = "aaa", Status = true },
new Person() { Name = "bbb", Status = true },
new Person() { Name = "ccc", Status = true },
new Person() { Name = "ddd", Status = true },
new Person() { Name = "eee", Status = true },
};
//Intermediate variable, to avoid the previous has not yet ended, the next time has begun
public static List<string> process = new List<string>();
public void Execute(IJobExecutionContext context)
{
//Equivalent to a database query
var pers = persions.Where(s => s.Status).ToList();
//Exclude the object that was executed the previous time
pers = pers.Where(s=> !process.Contains(s.Name)).ToList();
Action<List<Person>> doWork = (s) =>
{
process.AddRange(s.Select(n => n.Name));//Add to intermediate variable
DoWork(s);//Do something that can not be expected time (http request)
};
doWork.BeginInvoke(pers, (str) =>
{
//After DoWork() ends, organize the intermediate variables
if (pers != null && pers.Count() > 0)
{
foreach (var i in pers)
process.Remove(i.Name);
}
}, null);
Console.ReadKey();
}
public void DoWork(List<Person> _pers)
{
Thread.Sleep(1000 * 60 * 1 + 1000 * 10);//Simulate http requests (One minute 10 seconds)
var firstPer = persions.Where(s => s.Status).FirstOrDefault();
if (firstPer != null)
{
//Simulation to modify the table record
firstPer.Status = false;
}
}
}
因爲多個工作觸發器短,並且DoWork的()方法執行時間是不可預測的,它可能會導致多個線程同時訪問persions變量。我如何使用鎖定語句來處理這個問題?
**注意**:Execute()中有三個地方使用中間變量**進程** – qingyun1029
您只想鎖定(personListLock){/ * ... * /}'?你可以看到這是如何工作的[這個問題](https://stackoverflow.com/questions/6029804/how-does-lock-work-exactly)。請注意,如果是這樣的話,那麼您的問題很可能會以重複的方式關閉 – Icepickle
@lcepickle我希望這段代碼能夠在多線程中正常工作。謝謝 ! – qingyun1029