我需要将一些进程移动到异步。我有5个方法需要单独调用并在后台运行,以便用户可以继续他们的工作。
下面的测试代码似乎有效......但我还没有弄清楚如何返回指示任务已完成的信息(消息)。该类将从单独的窗体中调用,以便显示进度....
来自表格:
async void BtnGo_Click(object sender, System.EventArgs e)
{
label2.Text = @"Starting tasks...";
var progress = new Progress<string>(
p =>
{
label2.Text = p;
});
await TestTask.MyTestMain(progress);
}
班级:
public static class TestTask
{
public static Task MyTestMain(IProgress<string> pProgress)
{
return SomethingAsync(pProgress);
}
private static async Task SomethingAsync(IProgress<string> pProgress)
{
var t1 = SomeThing1(pProgress);
var t2 = SomeThing2(pProgress);
await Task.WhenAll(t1, t2);
if (pProgress != null) pProgress.Report(@"all tasks completed");
}
private static async Task SomeThing1()
{
await Task.Delay(9000);
var filename = @"c:\temp\tt1.txt";
if (File.Exists(filename))
File.Delete(filename);
using (TextWriter tw = new StreamWriter(filename))
{
await tw.WriteLineAsync(DateTime.Now.ToLongDateString());
}
if (pProgress != null) pProgress.Report(@"t1 completed");
}
private static async Task SomeThing2()
{
await Task.Delay(7000);
var filename = @"c:\temp\tt2.txt";
if (File.Exists(filename))
File.Delete(filename);
using (TextWriter tw = new StreamWriter(filename))
{
await tw.WriteLineAsync(DateTime.Now.ToLongDateString());
}
if (pProgress != null) pProgress.Report(@"t2 completed");
}
}
我想知道每项任务何时完成。任何帮助或指示将不胜感激。
修改的 我已编辑此帖以反映我的更改...我仍然无法将进度报告反馈给用户界面...任何想法?
答案 0 :(得分:1)
您正在进行IO绑定工作,您不需要使用线程池线程。
转换您的方法以使用StreamWriter
的异步API:
private static async Task FirstThingAsync()
{
var filename = @"c:\temp\tt1.txt";
if (File.Exists(filename))
File.Delete(filename);
using (TextWriter tw = new StreamWriter(filename))
{
await tw.WriteLineAsync(DateTime.Now);
}
}
第二种方法相同,然后您可以同时异步等待它们:
private static async Task SomethingAsync()
{
var firstThing = FirstThingAsync();
var secondThing = SecondThingAsync();
await Task.WhenAll(firstThing, secondThing);
}
修改强>
您永远无法拨打第一个Progress.Report
来电,因为当您在承诺式任务上致电InvalidOperationException
时,您的代码会抛出t.Start()
:
t1.Start();
await t1;
t2.Start();
await t2;
从两个方法调用返回的任务都是“热门任务”,这意味着它的操作已经开始。 Task.Start
上的文档说:
InvalidOperationException :任务未处于有效状态 开始。 可能已经启动,执行或取消或 它可能是以不支持直接的方式创建的 调度。
你没有看到这个例外的原因是因为你吞下它:
var t = SomethingAsync(pProgress);
当你没有等待异步操作时。您的方法调用应如下所示:
public static Task MyTestMain(IProgress<string> pProgress)
{
return SomethingAsync(pProgress);
}
async void BtnGo_Click(object sender, System.EventArgs e)
{
label2.Text = @"Starting tasks...";
var progress = new Progress<string>(
p =>
{
label2.Text = p;
});
await TestTask.MyTestMain(progress);
}