skip to Main Content

I have the following code structure:

private AutoResetEvent _renderCompleteEvent = new AutoResetEvent(false);

// GET: api/<controller>
[HttpGet]
public async Task<string> GetAsync()
{
    // Subscribe to the response from Redis publish
    _pubsub.Subscribe("x", (channel, message) => RenderComplete(message));

    // Ideally I would like to wait on RenderComplete and have it return a string here
    // string messageContent = await RenderComplete()..

    _renderCompleteEvent.WaitOne();

    return messageContent;
}

private void RenderComplete(string json)
{
    _renderCompleteEvent.Set();
}

Ideally I would like to be able to wait on a function call which would return when I get a message from Redis and the function would return the message content.

Instead I had to implement it using an AutoResetEvent and I would have to pass the message content back as a global class variable.

Is there a way to achieve what I want here to make the code a bit more elegant?

2

Answers


  1. Yes, you can use a TaskCompletionSource<T> to make pretty much anything awaitable:

    private TaskCompletionSource<string> _tcs = new TaskCompletionSource<string>();
    
    // GET: api/<controller>
    [HttpGet]
    public async Task<string> GetAsync()
    {
      // Subscribe to the response from Redis publish
      _pubsub.Subscribe("x", (channel, message) => RenderComplete(message));
    
      string messageContent = _tcs.Task;
    
      return messageContent;
    }
    
    private void RenderComplete(string json)
    {
      _tcs.TrySetResult(json);
    }
    

    Note that TaskCompletionSource<T> can only be completed once; it can’t be “reset”. So you would probably prefer a solution like this that combines the subscribing and message retrieval:

    // GET: api/<controller>
    [HttpGet]
    public async Task<string> GetAsync()
    {
      string messageContent = await GetMessageAsync();
    
      return messageContent;
    }
    
    private Task<string> GetMessageAsync()
    {
      var tcs = new TaskCompletionSource<string>();
      _pubsub.Subscribe("x", (channel, message) => tcs.TrySetResult(message));
      return tcs.Task;
    }
    

    You may also want to modify GetMessageAsync to handle things like unsubscribing and timing out if there’s no message.

    Login or Signup to reply.
  2. i did it and founded this solution to call minio async service in asp.netcore.

    your Service in controller

        [HttpGet]
        [Route("/api/getFileList")]
        public async Task<Object> getFileList()
        {
            var endpoint = "127.0.0.1";
            int port = 9000;
            var accessKey = "your accessKey ";
            var secretKey = "your secretKey";
    
            try
            {
                var minio = new MinioClient()
                                    .WithEndpoint(endpoint, port)
                                    .WithCredentials(accessKey, secretKey)
                                    //.WithSSL()
                                    .Build();
    
                var listFile = await getListFileName(minio);
    
                if (listFile != null)
                    return listFile;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return "";
        }
    

    get file list from minio service

        private TaskCompletionSource<List<string>> _tcs = new TaskCompletionSource<List<string>>();
    
    
        [Obsolete]
        private async Task<List<string>> getListFile(MinioClient minio)
        {
    
            var bucketName = "test";
            List<string> bucketKeys = new List<string>();
    
            IObservable<Item> observable = minio.ListObjectsAsync(bucketName, null, false);
    
            observable.Subscribe(item =>
             {
                 bucketKeys.Add(item.Key.ToString());
             },
            ex => Console.WriteLine("OnError: {0}", ex),
            () =>
            {
                _tcs.TrySetResult(bucketKeys);
            });
    
            return _tcs.Task.Result;
        }
    

    asp.net
    asp.netcore
    MinioClient
    ListObjectsAsync
    IObservable

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search