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

本文关键字:操作 异步 任务 何显示 显示 报告 | 更新日期: 2023-09-27 17:56:12

我需要将一些进程移动到异步状态。 我需要单独调用 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");
    }
}

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

编辑我已经编辑了这篇文章以反映我的更改...我仍然无法将进度报告返回给 UI...有什么想法吗?

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

您正在执行 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调用,因为你的代码在你调用 t.Start() promise 样式任务时会抛出InvalidOperationException

t1.Start();
await t1;
t2.Start();
await t2;

从两个方法调用返回的任务是"热任务",这意味着它的操作已经启动。Task.Start上的文档说:

无效操作异常:任务未处于有效状态 开始。它可能已经启动、执行或取消,或者 它可能是以不支持直接的方式创建的 调度。

没有看到该异常的原因是因为您正在吞下它:

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