首页 > 解决方案 > 为什么不调用后处理方法?

问题描述

我正在尝试将文件保存在两个不同的位置。当文件成功保存在任何位置时,我想向客户端返回成功。两个任务(t1,t2)注定要这样做。以下是我发现的案例:

如果 t1 保存成功,则将响应返回给客户端并继续 t2。T2后期,如果t2无法保存文件,则调用postprocessing处理t​​2数据。

但是如果 t1 无法保存成功则等待 t2 完成,现在如果 t2 保存成功,则对 t1 数据进行后处理。

如果 t1 和 t2 都无法保存,则返回失败。

简而言之,要返回成功,其中一个必须成功保存它,如果它只有一个成功保存,则对失败的一个进行后处理。

我已经启动了两项任务,等待一项完成。休息可以很容易地通过代码破译,如果您需要更多详细信息,请告诉我。我是从控制台应用程序中复制代码,而不是从实际应用程序中复制代码。因此,响应在主要方法中进行了注释。

// dummy class used for returning response
public class TaskResult
{
    public int status { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        //destination folder
        var desFolders = new List<string>
        {
            @"\\Files\00a807b3\013413a0\012216ad",
            @"\\Files\00a807b3\013413a0\012216ad\IdoNotExist" // to trigger failure case, IdoNotExist => does not exist
        };

        //base 64 string
        var content =
            "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==";

        var t1 = Task.Run(() => WriteFile(desFolders[0], content));
        var t2 = Task.Run(() => WriteFile(desFolders[1], content));

        // to track if file was ever saved
        bool anySuccess = false;

        int result = Task.WaitAny(t1, t2);

        if (result == 0)
        {
            var response = t1.Result;
            if (response.status == 1)
            {
                anySuccess = true;
                t2.ContinueWith(prevTask =>
                {
                    var t2Res = prevTask.Result;
                    if (t2Res.status == 0) // post processing if t2 could not save file
                        PostProcessing("t2");
                });
            }
        }
        else if (result == 1)
        {
            var response = t2.Result;
            if (response.status == 1)
            {
                anySuccess = true;
                t1.ContinueWith(prevTask =>
                {
                    var t1Res = prevTask.Result;
                    if (t1Res.status == 0)
                        PostProcessing("t1"); // post processing if t1 could not save file
                });
            }

        }


        // to check if completed task was not a success then wait for other running task 
        if (!anySuccess)
        {
            TaskResult waitedResponse = null;
            if (result == 0)
            {
                t2.Wait(); // wait for t2 as t1 was already completed
                waitedResponse = t2.Result;
                if (waitedResponse.status == 1)
                {
                    //if t2 was successful then post process t1
                    anySuccess = true;
                    t1.ContinueWith(prevTask => { PostProcessing("t1"); });
                }
            }
            else
            {
                t1.Wait();
                waitedResponse = t1.Result;
                if (waitedResponse.status == 1)
                {
                    //if t2 was successful then post process t1
                    anySuccess = true;
                    t2.ContinueWith(prevTask =>
                    {
                        var val = prevTask;
                        PostProcessing("t2");
                    });
                }
            }

        }

        if (!anySuccess)
        {
            //return failure;  
        }

        //return success


    }

    private static void PostProcessing(string t)
    {
        Console.WriteLine( $"post processing : {t}");
        Console.ReadLine();
        // insert record in database 
        // intentionally just not to make complex no argument is recived  for insertion
    }

    private static TaskResult WriteFile(string folder, string content)
    {
        var imageName = $"{Guid.NewGuid().ToString()}.jpg";
        var fullName = $@"{folder}\{imageName}";

        try
        {
            byte[] bytes = Convert.FromBase64String(content);
            using (var imageFile = new FileStream(fullName, FileMode.Create))
            {
                imageFile.WriteAsync(bytes, 0, bytes.Length);
                imageFile.FlushAsync();
            }

            return new TaskResult { status = 1 };
        }
        catch (Exception ex)
        {
            return new TaskResult { status = 0 };
        }
    }

}

尽管我看到保存到不存在的位置时出现故障,但这里从未调用过 PostProcessing 方法。我如何重构此代码以使其正常工作?

标签: c#.netasynchronous

解决方案


您的 WriteFile 方法应该是async+Task<TaskResult>作为返回值,因为您使用的是WriteAsync.

你也应该await WriteAsync因为它是一种基于任务的方法


推荐阅读