【发布时间】:2021-05-20 15:03:16
【问题描述】:
我需要一些关于多项任务和报告 C# 进度的帮助。我正在尝试在Xamarin 中使用,但为了简化,以下代码 sn-ps 是使用WindowsForm (WinForms) 制作的。
我需要运行一个执行任务的加载表单。此任务应向加载表单报告其进度,更改控制状态消息标签的属性。
到目前为止,我尝试的所有方法都不起作用。任务运行时,加载表单不会更新其状态消息。那么,我应该在哪里声明 Progress 变量,我应该如何将它传递给任务?这种沟通应该如何进行?
这是我的主要形式:
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
frmLoading loading = new frmLoading();
// THIS BLOCK SHOUD BE HERE?
Progress<string> progress = new Progress<string>(updateValue =>
{
loading.ChangeMessage(updateValue);
});
//END
loading.Start(() => Count(loading.progress)); //PROGRESS from LOADING or from this class?
loading.ShowDialog();
}
private async Task<int> Count(IProgress<string> progress)
{
int returnValue = 0;
for (int i = 0; i < 100; i++)
{
Thread.Sleep(100);
if (progress != null)
{
if (i <= 20)
{
progress.Report("Keep waiting...");
}
else if (i > 20 && i <= 40)
{
progress.Report("Hold on...");
}
else if (i > 40 && i <= 80)
{
progress.Report("So close!");
}
else
{
progress.Report("All right!");
}
}
returnValue = i;
}
await Task.Run(() => { MessageBox.Show("Completed!"); });
return returnValue;
}
}
这是我的加载表单:
public partial class frmLoading : Form, INotifyPropertyChanged
{
private Func<Task<int>> taskParam;
public Progress<string> progress;
public event PropertyChangedEventHandler PropertyChanged;
public string currentMessage { get; set; }
public frmLoading()
{
InitializeComponent();
progress = new Progress<string>(updateMessage => {
currentMessage = updateMessage;
});
}
public async Task<int> StartTask()
{
return await taskParam();
}
private async void button1_Click(object sender, EventArgs e)
{
await StartTask();
}
public void Start(Func<Task<int>> taskParam)
{
this.taskParam = taskParam;
}
public void ChangeMessage(string newMessage)
{
currentMessage = newMessage;
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
if (propertyName.Equals(nameof(currentMessage)))
lblProgress.Text = currentMessage;
}
}
【问题讨论】:
-
您使用
Thread.Sleep()表示工作,但这只会阻塞线程。它没有为线程提供任何响应窗口消息的方式,而更新窗口需要这些消息。使用Task.Delay()代替,每个副本。
标签: c# multithreading winforms xamarin task