在函数执行过程中将进度条与函数中的值链接起来



我已经创建了一个类,公共函数在执行过程中返回一个列表公共int在函数结束时增加到100,进度条的值在函数期间增加如何使在类和WPF形式的进度条之间的公共int同步最后,我想要list作为结果,WeekListsProgress作为进度条值

public class SchedHandler
{
public static List<Subject4Sched> SubSchedList = GetSchedSubList();
public static int WeekSum = SubSchedList.Sum(x => x.WeekCount);
public static int AssignSum = SubSchedList.Sum(x => x.Assigned);
public static SchoolEntitiesProFinal ProDb;
public static int WeekListsProgress = 0;
public static List<SubWeekCount> GetSubList(int semId)
{
ProDb = new SchoolEntitiesProFinal();
List<sp_GetSubWeekCountList_Result> subs = ProDb.sp_GetSubWeekCountList(semId).ToList();
return subs.Select(item => new SubWeekCount(item.subid, item.subject, item.sessioncount)).ToList();
}
public List<SubWeekCount> SubList = GetSubList(1);
//1- Insert Subjects With 0 Assigned
public static void InsertSubjects(int subid,string subName, int week, int ass)
{
var sub = new tbl_schedule();
sub.subid = subid;
sub.subname = subName;
sub.weekly = week;
sub.assigned = ass;

try
{
using (var db = new SchoolEntitiesProFinal())
{
db.tbl_schedule.Add(sub);
db.SaveChanges();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public static void UpdtaeSubjects(int subid)
{
tbl_schedule sub = ProDb.tbl_schedule.FirstOrDefault(x => x.subid == subid);

try
{
if (sub != null) sub.assigned = sub.assigned + 1;
ProDb.SaveChanges();
}
catch (Exception)
{
MessageBox.Show("Error With Databse!!!");
}
}
public static void RemoveSubjects(int subid)
{
tbl_schedule sub = ProDb.tbl_schedule.FirstOrDefault(x => x.subid == subid);
try
{
if (sub!=null)
{
if (sub.assigned == sub.weekly)
{
ProDb.tbl_schedule.Remove(sub);
ProDb.SaveChanges();
} 
}
}
catch (Exception)
{
MessageBox.Show("Error With Databse!!!");
}
}
public static void RemoveAllSubjects()
{
List<tbl_schedule> sub = ProDb.tbl_schedule.ToList();
try
{
ProDb.tbl_schedule.RemoveRange(sub);
ProDb.SaveChanges();

}
catch (Exception)
{
MessageBox.Show("Error With Databse!!!");
}
}
public static int GetSubAssigned(int subid)
{
ProDb = new SchoolEntitiesProFinal();
var sub = ProDb.tbl_schedule.FirstOrDefault(x => x.subid == subid);
int count = 0;
if (sub != null) count = sub.assigned;
return count;
}
public static List<Subject4Sched> GetSchedSubList()
{
ProDb = new SchoolEntitiesProFinal();
var subs = ProDb.tbl_schedule.ToList();
return subs.Select(item => new Subject4Sched(item.subid, item.subname, item.weekly, item.assigned)).ToList();
}
public static Subject4Sched GetSub()
{
ProDb = new SchoolEntitiesProFinal();
var f = ProDb.tbl_schedule.First();
var sub = new Subject4Sched(f.subid, f.subname,f.weekly,f.assigned);
return sub;
}
public static List<Sessions> WeekLists(int semId)
{
WeekListsProgress = 0;
var sat = new List<Subject4Sched>();
var sun = new List<Subject4Sched>();
var mon = new List<Subject4Sched>();
var tues = new List<Subject4Sched>();
var wed = new List<Subject4Sched>();
var thur = new List<Subject4Sched>();
var fri = new List<Subject4Sched>();
string[] weekEnds = File.ReadAllLines(@"C:Program FilesSchool ManagerPars TextWeekEnds.txt");
var holidaylist = weekEnds.Select(line => line.Split(',')).Select(tokens => tokens[0]).ToList();
// Get Subjects For Semester 
var subList = GetSubList(semId);
RemoveAllSubjects();
int v = 0;
foreach (var sub in subList)
{
InsertSubjects(sub.SubId, sub.SubName, sub.WeekCount, 0);
v += (20/subList.Count);
}
WeekListsProgress = 20;
int weekDaysCount = 7 - holidaylist.Count;
int sessionsCount = subList.Sum(x => x.WeekCount);
var sessionsPerDay = Math.Ceiling(Convert.ToDouble(sessionsCount) / Convert.ToDouble(weekDaysCount));
for (int x = 0; x < sessionsCount; x++)
{
foreach (var sched in SubSchedList.ToList())
{
for (int i = 0; i < sched.WeekCount; i++)
{
if (i < sched.WeekCount)
{
if (sat.Count < sessionsPerDay && !holidaylist.Contains(DayOfWeek.Saturday.ToString()))
{
int subCount = sat.Count(y => y.SubId == sched.SubId) +
sun.Count(y => y.SubId == sched.SubId) +
mon.Count(y => y.SubId == sched.SubId) +
tues.Count(y => y.SubId == sched.SubId) +
wed.Count(y => y.SubId == sched.SubId) +
thur.Count(y => y.SubId == sched.SubId) +
fri.Count(y => y.SubId == sched.SubId);
WeekListsProgress += 60 / sessionsCount;
if (subCount < sched.WeekCount)
{
sat.Add(new Subject4Sched(sched.SubId, sched.SubName, sched.WeekCount, sched.Assigned++));
UpdtaeSubjects(sched.SubId);
i++;
x++; 
}
}
}
else
{
break;
}
if (i < sched.WeekCount)
{
if (sun.Count < sessionsPerDay && !holidaylist.Contains(DayOfWeek.Sunday.ToString()))
{
int subCount = sat.Count(y => y.SubId == sched.SubId) +
sun.Count(y => y.SubId == sched.SubId) +
mon.Count(y => y.SubId == sched.SubId) +
tues.Count(y => y.SubId == sched.SubId) +
wed.Count(y => y.SubId == sched.SubId) +
thur.Count(y => y.SubId == sched.SubId) +
fri.Count(y => y.SubId == sched.SubId);
WeekListsProgress += 60 / sessionsCount;
if (subCount < sched.WeekCount)
{
sun.Add(new Subject4Sched(sched.SubId, sched.SubName, sched.WeekCount,
sched.Assigned++));
UpdtaeSubjects(sched.SubId);
i++;
x++;
}
}
}
else
{
break;
}
if (i < sched.WeekCount)
{
if (mon.Count < sessionsPerDay && !holidaylist.Contains(DayOfWeek.Monday.ToString()))
{
int subCount = sat.Count(y => y.SubId == sched.SubId) +
sun.Count(y => y.SubId == sched.SubId) +
mon.Count(y => y.SubId == sched.SubId) +
tues.Count(y => y.SubId == sched.SubId) +
wed.Count(y => y.SubId == sched.SubId) +
thur.Count(y => y.SubId == sched.SubId) +
fri.Count(y => y.SubId == sched.SubId);
WeekListsProgress += 60 / sessionsCount;
if (subCount < sched.WeekCount)
{
mon.Add(new Subject4Sched(sched.SubId, sched.SubName, sched.WeekCount,
sched.Assigned++));
UpdtaeSubjects(sched.SubId);
i++;
x++;
}
}
}
else
{
break;
}
if (i < sched.WeekCount)
{
if (tues.Count < sessionsPerDay && !holidaylist.Contains(DayOfWeek.Tuesday.ToString()))
{
int subCount = sat.Count(y => y.SubId == sched.SubId) +
sun.Count(y => y.SubId == sched.SubId) +
mon.Count(y => y.SubId == sched.SubId) +
tues.Count(y => y.SubId == sched.SubId) +
wed.Count(y => y.SubId == sched.SubId) +
thur.Count(y => y.SubId == sched.SubId) +
fri.Count(y => y.SubId == sched.SubId);
WeekListsProgress += 60 / sessionsCount;
if (subCount < sched.WeekCount)
{
tues.Add(new Subject4Sched(sched.SubId, sched.SubName, sched.WeekCount,
sched.Assigned++));
UpdtaeSubjects(sched.SubId);
i++;
x++;
}
}
}
else
{
break;
}
if (i < sched.WeekCount)
{
if (wed.Count < sessionsPerDay && !holidaylist.Contains(DayOfWeek.Wednesday.ToString()))
{
int subCount = sat.Count(y => y.SubId == sched.SubId) +
sun.Count(y => y.SubId == sched.SubId) +
mon.Count(y => y.SubId == sched.SubId) +
tues.Count(y => y.SubId == sched.SubId) +
wed.Count(y => y.SubId == sched.SubId) +
thur.Count(y => y.SubId == sched.SubId) +
fri.Count(y => y.SubId == sched.SubId);
WeekListsProgress += 60 / sessionsCount;
if (subCount < sched.WeekCount)
{
wed.Add(new Subject4Sched(sched.SubId, sched.SubName, sched.WeekCount,
sched.Assigned++));
UpdtaeSubjects(sched.SubId);
i++;
x++;
}
}
}
else
{
break;
}
if (i < sched.WeekCount)
{
if (thur.Count < sessionsPerDay && !holidaylist.Contains(DayOfWeek.Thursday.ToString()))
{
int subCount = sat.Count(y => y.SubId == sched.SubId) +
sun.Count(y => y.SubId == sched.SubId) +
mon.Count(y => y.SubId == sched.SubId) +
tues.Count(y => y.SubId == sched.SubId) +
wed.Count(y => y.SubId == sched.SubId) +
thur.Count(y => y.SubId == sched.SubId) +
fri.Count(y => y.SubId == sched.SubId);
WeekListsProgress += 60 / sessionsCount;
if (subCount < sched.WeekCount)
{
thur.Add(new Subject4Sched(sched.SubId, sched.SubName, sched.WeekCount,
sched.Assigned++));
UpdtaeSubjects(sched.SubId);
i++;
x++;
}
}
}
else
{
break;
}
if (i < sched.WeekCount)
{
if (fri.Count < sessionsPerDay && !holidaylist.Contains(DayOfWeek.Friday.ToString()))
{
int subCount = sat.Count(y => y.SubId == sched.SubId) +
sun.Count(y => y.SubId == sched.SubId) +
mon.Count(y => y.SubId == sched.SubId) +
tues.Count(y => y.SubId == sched.SubId) +
wed.Count(y => y.SubId == sched.SubId) +
thur.Count(y => y.SubId == sched.SubId) +
fri.Count(y => y.SubId == sched.SubId);
WeekListsProgress += 60 / sessionsCount;
if (subCount < sched.WeekCount)
{
fri.Add(new Subject4Sched(sched.SubId, sched.SubName, sched.WeekCount,
sched.Assigned++));
UpdtaeSubjects(sched.SubId);
i++;
x++;
}
}
}
else
{
break;
}
}
}
}
WeekListsProgress = 80;
int[] counts = {sat.Count, sun.Count, mon.Count, tues.Count, wed.Count, thur.Count, fri.Count};
////////////////////////////////////////////////////////////////////////////////////////////////////
var sList=new List<Sessions>();
for (int i = 0; i < counts.Max(); i++)
{
string s1="";string s2 = "";string s3 = "";string s4 = ""; string s5 = ""; string s6 = ""; string s7 = "";
if (sat.Count>i)
{
s1 = sat[i].SubName;
}
if (sun.Count > i)
{
s2 = sun[i].SubName;
}
if (mon.Count > i)
{
s3 = mon[i].SubName;
}
if (tues.Count > i)
{
s4 = tues[i].SubName;
}
if (wed.Count > i)
{
s5 = wed[i].SubName;
}
if (thur.Count > i)
{
s6 = thur[i].SubName;
}
if (fri.Count > i)
{
s7 = fri[i].SubName;
}

sList.Add(new Sessions(i,s1,s2,s3,s4,s5,s6,s7));
WeekListsProgress += 20/counts.Max();
}
WeekListsProgress = 100;
return sList;
}


}
}

我不建议使用类属性来报告进度,尤其是静态属性。一个原因是,它使方法不是线程安全的,但它也可以使类更难使用,因为它不明显,如果任何方法更新进度。

我更喜欢的方法是在你的方法中取一个参数,然后更新这个参数的progress属性。就像

public class ProgressDestination{
public double Progress {get;set;} // in range 0,1
public string Description {get;set;} // Optional text 
}

要将其与UI连接,我更喜欢使用轮询器

public class ProgressPoller : INotifyPropertyChanged
{
public ProgressDestination Progress { get; } = new ProgressDestination();
private readonly DispatcherTimer timer;
public ProgressPoller()
{
timer = new DispatcherTimer();
timer.Tick += OnTick;
timer.Interval = TimeSpan.FromSeconds(0.2);
}
private void OnTick(object sender, EventArgs e)
{
Value = (int) (Progress.Progress * MaxValue);
Description = Progress.Description;
OnPropertyChanged(nameof(Value));
OnPropertyChanged(nameof(Description));
}
public int Value { get; set; }
public string Description { get; set; }
public int MaxValue { get; } = 100;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

以便进度条可以简单地绑定到轮询器的value属性。

<ProgressBar 
x:Name="progressBar"
Minimum ="0" 
Maximum="{Binding poller.MaxValue}" 
Value="{Binding poller.Value, Mode=OneWay}">

这确保进度条在主线程上更新,并且它有一个固定的更新率,无论后台代码更新进度变量的速度有多快。

这是一种简化,例如,如果没有操作正在进行,它可能需要某种方法来重置或转动轮询器。或者在多个操作可能并发运行时将操作排队的方法。也可以扩展此方法以允许多个分层进度报告。

您可以在SchedHandler类中定义一个事件,并将该事件发送到创建类的每个实例的类的实例,并将更改应用于控件。

public class SchedHandler
{
public delegate void ProgressChangeDelegate(double Persentage);
public static event ProgressChangeDelegate OnProgressChanged;
public SchedHandler()
{ 
OnProgressChanged += delegate { };
}
public static List<Sessions> WeekLists(int semId)
{
///.........
WeekListsProgress += 60 / sessionsCount;
OnProgressChanged(WeekListsProgress);
///.........
}
//..........................
//..........................
}

当然,一定要在需要更新Progressber值的地方调用OnProgressChanged

现在使用

SchedHandler.OnProgressChanged += schedHandler_OnProgressChanged;
private void schedHandler_OnProgressChanged(double Persentage)
{
Func<int> del = delegate()
{
progressbar1.Percentage = Persentage;
return 0;
};
Dispatcher.Invoke(del);
}

https://www.youtube.com/watch?v=zQMNFEz5IVU&t=1s

private async void Button_Click(object sender, RoutedEventArgs e)
{
var sl = new List<Sessions>();
var progress = new Progress<int>(value =>
{
pbWeekList.Value =value ;
});
await Task.Run(() => sl= SchedHandler.WeekLists(1, progress));
dg.ItemsSource = sl;
}

但首先必须改成

public static List<Sessions> WeekLists(int semId,IProgress<int> progress)
{
WeekListsProgress = 0;
progress.Report(WeekListsProgress);
/////////////////////
/////////////////
////////////////
Thread.Sleep(100);
WeekListsProgress = 100;
progress.Report(WeekListsProgress);
return sList;
}

最新更新