Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling 2 methods asynchronously

I'm not sure if my program does exactly what i want or if it could be coded better. Target would be to call the 2 Methods (CreateHeaderAsync, CombineFilesAsync) and let them work parallel.

I don't think this is the right or a good way to write those ...Async() methods because that looks pretty unclean.

And couldn't i combine the first 4 lines in my CreateFile method to reduce unimportant code and make it more readable?

public void CreateFile(string path)
{
    Task<byte[]> headerTask = CreateHeaderAsync();
    Task<byte[]> filesTask = CombineFilesAsync();
    byte[] header = headerTask.Result;
    byte[] files = filesTask.Result;

    byte[] combined = new byte[header.Length + files.Length];

    Buffer.BlockCopy(header, 0, combined, 0, header.Length);
    Buffer.BlockCopy(files, 0, combined, header.Length, files.Length);

    Task.Factory.StartNew(() => File.WriteAllBytes(path, combined));
}

private Task<byte[]> CreateHeaderAsync()
{
    return Task.Factory.StartNew(() =>
    {
        StringBuilder sb = new StringBuilder();
        int position = 0;
        foreach (ByteFile file in _files)
        {
            sb.Append(file + "?" + position + Environment.NewLine);
            position += file.Length;
        }
        return Encoding.UTF8.GetBytes(sb + "--header_end--" + Environment.NewLine);
    });
}

private Task<byte[]> CombineFilesAsync()
{
    return Task.Factory.StartNew(() =>
    {
        ByteFile[] arrays = _files.ToArray();

        byte[] rv = new byte[arrays.Sum(a => a.Length)];
        int offset = 0;
        foreach (ByteFile t in arrays)
        {
            var array = Encryption.EncryptBytes(t.Content, "password");

            Buffer.BlockCopy(array, 0, rv, offset, array.Length);
            offset += array.Length;
        }
        return rv;
    });
}
like image 320
Martin Niederl Avatar asked Sep 27 '26 20:09

Martin Niederl


1 Answers

Target would be to call the 2 Methods (CreateHeaderAsync, CombineFilesAsync) and let them work parallel.

Then try Task.WhenAll to asynchronously await their completion.

  public async Task CreateFile(string path)
    {
        Task<byte[]> headerTask = CreateHeaderAsync();
        Task<byte[]> filesTask = CombineFilesAsync();

        var allResults = await Task.WhenAll(headerTask, filesTask);
        byte[] header = allResults[0];
        byte[] files = allResults[1];

Reply to the comment

Couldn't he also just do byte[] header = await headerTask; byte[] files = await filesTask; Does it matter that he waits for one task even though the other may complete before it?

Ok. This is true. The only thing is that two await could resume the caller once more. So I would prefer a single final callback.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!