【问题标题】:Is there a way I can start async task on create but not async oncreate Xamarin有没有一种方法可以在创建时启动异步任务但不能在创建时启动异步任务 Xamarin
【发布时间】:2016-03-12 06:51:10
【问题描述】:

我希望应用程序执行异步任务,但要先显示内容,然后启动异步任务。当我使用protected async override void OnCreate(Bundle bundle) 时,在执行异步任务之前,我看不到按钮等内容或屏幕上的内容。这完全使得使用异步任务毫无用处。

我可以通过Button.Click 实现它。但话又说回来,这不是我想要的。我想在OnCreate 设置所有视图后立即启动异步任务。也许问题出在protected async override void OnCreate(Bundle bundle)

还有其他方法可以启动任务onCreate吗?

这是我的代码。

[Activity(Label = "NewsDetails")]
public class NewsDetails : Activity {
  protected async override void OnCreate(Bundle savedInstanceState) {
    base.OnCreate(savedInstanceState);
    SetContentView(Resource.Layout.NewsDetails);
    TextView Title = FindViewById<TextView>(Resource.Id.textTitle);
    TextView Source = FindViewById<TextView>(Resource.Id.textSource);
    WebView webDisplay = FindViewById<WebView>(Resource.Id.webDisplay);
    string thisid=Intent.GetStringExtra ("id");
    string url = "http://MyApiUrl/";
    url = url + thisid;
    var result = await GetNewsAsync(url);
    Title.Text = result.GetString("Title");
    Source.Text = result.GetString("Source");
    string ExternalReference = result.GetString("ExternalReference");
    webDisplay.Settings.JavaScriptEnabled = true;
    webDisplay.LoadUrl(ExternalReference);
  }
  private async Task<JSONObject> GetNewsAsync(string url) {
    // Create an HTTP web request using the URL:
    // Send the request to the server and wait for the response:
    // Return some JSONObject after async task here
    // Create an HTTP web request using the URL:
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
    request.ContentType = "application/json";
    request.Method = "GET";
    // Send the request to the server and wait for the response:
    using (WebResponse response = await request.GetResponseAsync()) {
      // Get a stream representation of the HTTP web response:
      using (Stream stream = response.GetResponseStream()) {
        // Use this stream to build a JSON document object:
        JSONObject jsonResponse;
        Stream jsonDoc = stream;
        Console.Out.WriteLine("Response: {0}", jsonDoc.ToString());
        StreamReader reader = new StreamReader(stream, Encoding.UTF8);
        String responseString = reader.ReadToEnd();
        jsonResponse = new JSONObject(responseString);
        JSONObject jResult = jsonResponse.GetJSONObject("Result");
        return jResult;
      }
    }
  }
}

我想知道我是否做错了什么,或者是否有完全不同的方法来实现我想要做的事情。

欢迎对代码提出任何建议。

编辑:async Task&lt;JSONObject&gt; GetNewsAsync 的代码。

【问题讨论】:

  • GetNewsAsync 真的是异步的吗?我的意思是该方法是否在等待某些东西?你介意发布它的代码
  • @SriramSakthivel 添加了等待响应流的 GetNewsAsync 代码
  • StreamReader.ReadToEnd 是同步调用,请改用await reader.ReadToEndAsync。或者使用HttpClient api。
  • @SriramSakthivel 谢谢你的好建议!我完全错过了同步 .ReadToEnd

标签: c# android asynchronous xamarin async-await


【解决方案1】:

我不建议将 OnCreate 方法标记为异步。

试试这样的:

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);

    SetContentView(Resource.Layout.NewsDetails);

    TextView Title = FindViewById<TextView>(Resource.Id.textTitle);
    TextView Source = FindViewById<TextView>(Resource.Id.textSource);
    WebView webDisplay = FindViewById<WebView>(Resource.Id.webDisplay);
    webDisplay.Settings.JavaScriptEnabled = true;

    string thisid=Intent.GetStringExtra ("id");
    string url = "http://MyApiUrl/";
    url = url + thisid;

    GetNewsAsync(url).ContinueWith(t=>
    {
        var result = t.Result;

        Title.Text = result.GetString("Title");
        Source.Text = result.GetString("Source");
        string ExternalReference = result.GetString("ExternalReference");

        webDisplay.LoadUrl(ExternalReference);
    });
  }

【讨论】:

  • 你不推荐async void OnCreate()方法的原因是什么?
  • 我花了 2 天时间才了解 ContinueWith 及其用法。我一直在使用异步 OnCreate,我知道这不是一个好习惯。我完全同意你上面给出的解决方案。它会让很多事情变得容易得多。 快乐编码
  • @Robin-ManuelThiel 在某些情况下可能会导致死锁。
猜你喜欢
  • 2018-02-24
  • 1970-01-01
  • 2019-12-20
  • 2012-11-09
  • 1970-01-01
  • 2023-03-31
  • 2015-10-30
  • 2016-01-15
  • 1970-01-01
相关资源
最近更新 更多