如何显示/报告任务(异步)操作的进度?

时间:2015-06-15 13:44:52

标签: c# winforms asynchronous async-await

我需要将一些进程移动到异步。我有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");
    }
}

我想知道每项任务何时完成。任何帮助或指示将不胜感激。

修改的 我已编辑此帖以反映我的更改...我仍然无法将进度报告反馈给用户界面...任何想法?

1 个答案:

答案 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);
}