【问题标题】:Using async/await to return the result of a Xamarin.Forms dependency service callback?使用 async/await 返回 Xamarin.Forms 依赖服务回调的结果?
【发布时间】:2018-07-13 14:33:31
【问题描述】:

我有一个 Xamarin Forms 项目并实现了一个依赖服务来发送 SMS,但我不知道如何将设备无关的回调转换为异步等待,以便我可以返回它。例如,在我的 iOS 实现中,我有类似的东西:

[assembly: Xamarin.Forms.Dependency(typeof(MySms))]
namespace MyProject.iOS.DS
{
    class MySms : IMySms
    {
        // ...

       public void SendSms(string to = null, string message = null)
        {
            if (MFMessageComposeViewController.CanSendText)
            {
                MFMessageComposeViewController smsController= new MFMessageComposeViewController();
                // ...
                smsController.Finished += SmsController_Finished;
            }
        }
    }
    private void SmsController_Finished(object sender, MFMessageComposeResultEventArgs e)
    {
        // Convert e.Result into my smsResult enumeration type
    }
}

我可以将public void SendSms 更改为public Task<SmsResult> SendSmsAsyc,但是我如何等待 Finished 回调并获得它的结果,以便我可以让 SendSmsAsync 返回它?

【问题讨论】:

  • 你为什么要这么做?
  • 因为当我调用我的 SendSms 函数时,我需要取回操作的结果,例如:var smsResult = await DependencyService.Get<IMySms>().SendSms(to: toSmsNumber, message: smsMessage);

标签: c# xamarin.forms


【解决方案1】:
public interface IMySms
{
    Task<bool> SendSms(string to = null, string message = null);
}

public Task<bool> SendSms(string to = null, string message = null)
{
    //Create an instance of TaskCompletionSource, which returns the true/false
    var tcs = new TaskCompletionSource<bool>();

    if (MFMessageComposeViewController.CanSendText)
    {
        MFMessageComposeViewController smsController = new MFMessageComposeViewController();

        // ...Your Code...             

        //This event will set the result = true if sms is Sent based on the value received into e.Result enumeration
        smsController.Finished += (sender, e) =>
        {
             bool result = e.Result == MessageComposeResult.Sent;
             //Set this result into the TaskCompletionSource (tcs) we created above
             tcs.SetResult(result);
        };
    }
    else
    {
        //Device does not support SMS sending so set result = false
        tcs.SetResult(false);
    }
    return tcs.Task;
}

这样称呼:

bool smsResult = await DependencyService.Get<IMySms>().SendSms(to: toSmsNumber, message: smsMessage);

【讨论】:

  • 这正是我最终所做的,它就像一个魅力。当我问这个问题时,我什至不知道 TaskCompletionSource 存在。一旦我了解了它是什么,我就意识到我必须将 Finished 事件作为一个匿名函数内联,而不是把它作为一个单独的函数。我忙于我的项目,忘了回来发布答案。
  • 你的 android 实现是什么样的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-04
  • 2020-09-21
  • 2018-09-05
  • 1970-01-01
  • 2022-08-22
相关资源
最近更新 更多