0

I am running an await Task< >.Run(() => inside an async method.
The code in the await runs to competition but never returns.
The next line after the await never gets called.
Anyone have any input?

How async method is called

var task1 = ConvertToMagickImageAsync(tpFileInfo, fileInfo, density, inputModel.Quality);

task1.Wait();

Async method

protected virtual async Task<IXPubMagickImageOutputModel> ConvertToMagickImageAsync(
   Tuple<string, string, string> tpFileInfo
    , Tuple<IXPubMagickFileModel, IXPubMagickFileModel, IXPubMagickFileModel> fileInfo
    , Tuple<double, double, double> density
    , int quality
    )
{
    string error;
    var outputModel = new XPubMagickImageOutputModel
    {
        ResultContent = new SortedDictionary<int, IXPubMagickImageNameModel>()
    };

    MagickFormat extension = fileInfo.Item3.FileExtension switch
    {
        "png" => MagickFormat.Png,
        "jpg" => MagickFormat.Jpg,
        "jpeg" => MagickFormat.Jpeg,
        "bmp" => MagickFormat.Bmp,
        _ => MagickFormat.Jpg,
    };

    var magickSettings = new MagickReadSettings();
    if (density.Item1 > 0)
        magickSettings.Density = new Density(density.Item1);
    else
        magickSettings.Density = new Density(density.Item2, density.Item3);
  var ret= await Task< IXPubMagickImageOutputModel>.Run(() =>
    {
        try
        {
            using (var images = new MagickImageCollection())
            {
                var page = 0;
                images.Read(tpFileInfo.Item1, magickSettings);
                ////if (images.Count > 0 && images[0].Format == MagickFormat.Pdf)
                if (images.Count > 0)
                {
                    var sb = new StringBuilder(tpFileInfo.Item2);
                    sb.Append(@"\").Append(fileInfo.Item1.FileName);

                    var sb1 = new StringBuilder(tpFileInfo.Item3);
                    sb1.Append(".").Append(extension.ToString().ToLower());

                    foreach (var image in images)
                    {
                        image.Quality = quality;
                        image.Format = extension;
                        outputModel.ResultContent[page] = new XPubMagickImageNameModel
                        {
                            MagickImage = new MagickImage(image),
                            ImageName = $"{sb}_{page}_{sb1}"
                        };
                        page++;

                        //outputModels.Add(outputModel);
                    }// end foreach (var image in images)
                }  // end if (images.Count > 0 && images[0].Format == MagickFormat.Pdf)
            }

            error = String.Empty;
            outputModel.Result = XPubMagickOperationResultEnum.Success;

        }
        catch (Exception ex)
        {
            error = $"Exception: {ex.Message}";
            outputModel.Result = XPubMagickOperationResultEnum.ErrorMagickReadFailure;
        }
        return outputModel;
    });
    int a = 1;
    //}  // end using (var images = new MagickImageCollection())
    return ret;
}
GSerg
  • 76,472
  • 17
  • 159
  • 346
srf
  • 21
  • 1
  • 2

1 Answers1

0

You don't really need to await in the method. Just return the task and await outside in the Task.Wait()

 var task1 = ConvertToMagickImageAsync(tpFileInfo, fileInfo, density, inputModel.Quality);
    
    
task1.Wait();

And method won't be async anymore

protected virtual Task<IXPubMagickImageOutputModel> ConvertToMagickImageAsync(
   Tuple<string, string, string> tpFileInfo
    , Tuple<IXPubMagickFileModel, IXPubMagickFileModel, IXPubMagickFileModel> fileInfo
    , Tuple<double, double, double> density, int quality)
{
    string error;
    var outputModel = new XPubMagickImageOutputModel
    {
        ResultContent = new SortedDictionary<int, IXPubMagickImageNameModel>()
    };

    MagickFormat extension = fileInfo.Item3.FileExtension switch
    {
        "png" => MagickFormat.Png,
        "jpg" => MagickFormat.Jpg,
        "jpeg" => MagickFormat.Jpeg,
        "bmp" => MagickFormat.Bmp,
        _ => MagickFormat.Jpg,
    };

    var magickSettings = new MagickReadSettings();
    if (density.Item1 > 0)
        magickSettings.Density = new Density(density.Item1);
    else
        magickSettings.Density = new Density(density.Item2, density.Item3);
  return Task<IXPubMagickImageOutputModel>.Run(() =>
    {
        try
        {
            using (var images = new MagickImageCollection())
            {
                var page = 0;
                images.Read(tpFileInfo.Item1, magickSettings);
                ////if (images.Count > 0 && images[0].Format == MagickFormat.Pdf)
                if (images.Count > 0)
                {
                    var sb = new StringBuilder(tpFileInfo.Item2);
                    sb.Append(@"\").Append(fileInfo.Item1.FileName);

                    var sb1 = new StringBuilder(tpFileInfo.Item3);
                    sb1.Append(".").Append(extension.ToString().ToLower());

                    foreach (var image in images)
                    {
                        image.Quality = quality;
                        image.Format = extension;
                        outputModel.ResultContent[page] = new XPubMagickImageNameModel
                        {
                            MagickImage = new MagickImage(image),
                            ImageName = $"{sb}_{page}_{sb1}"
                        };
                        page++;

                        //outputModels.Add(outputModel);
                    }// end foreach (var image in images)
                }  // end if (images.Count > 0 && images[0].Format == MagickFormat.Pdf)
            }

            error = String.Empty;
            outputModel.Result = XPubMagickOperationResultEnum.Success;

        }
        catch (Exception ex)
        {
            error = $"Exception: {ex.Message}";
            outputModel.Result = XPubMagickOperationResultEnum.ErrorMagickReadFailure;
        }
        return outputModel;
    });
}
Mocas
  • 1,403
  • 13
  • 20
  • 1
    This [changes observable behaviour](https://stackoverflow.com/q/21033150/11683), which may not be desired. It is also a mere hack if only used to avoid the deadlock (there are proper ways to avoid it). – GSerg May 23 '21 at 20:12
  • The accepted answer in the question above says "the async/await version is more prone to dead-locking on a non-default synchronization context." And advises of "Change it to a non-async version and it won't dead-lock" – Mocas May 23 '21 at 20:25