【问题标题】:When I call a method with Task.Run() does it have to be an async method?当我使用 Task.Run() 调用方法时,它必须是异步方法吗?
【发布时间】:2018-12-31 07:48:45
【问题描述】:

我的代码如下所示:

    async public Task Btn(int pts)
    {
        switch (Settings.mode)
        {
            case MO.Assign:
            case MO.Learn:
                break;
            case MO.Quiz:
                await Task.Run(() => App.DB.IncrementPoints(phrase, 1));
                await Task.Delay(250);
                break;
            case MO.Practice:
                Device.BeginInvokeOnMainThread(() =>
                {
                    vm.Points = new String('☆', phrase.Points + pts);
                });
                await Task.Run(() =>
                {
                    App.DB.IncrementPoints(phrase, pts);
                    App.DB.IncrementHistory(HIST.Views);
                });
                await Task.Delay(250);
                break;
        }
        App.selectedPhrases = null;
        timer2Seconds = 2;
    }


    public void IncrementPoints(Phrase phrase, int pts)
    {
        lock (l)
        {
            db2.Execute("UPDATE phrase SET Points = Points + " + pts +
                        " WHERE PhraseId = '" + phrase.PhraseId + "'");
        }
    }

我对 Task.Run 和等待有点困惑。首先,我希望它能够更新屏幕:

vm.Points = new String('☆', phrase.Points + pts);

然后我想要更新数据库,然后有 250 毫秒的延迟。

但是我的方法 IncrementPoints 不是异步方法可以吗?

【问题讨论】:

  • 我对刚刚删除的评论的回复:感谢您的意见。我使用它是因为我认为这可能是最好的方法,但根据你刚才所说的,也许它是矫枉过正的。使用 Task.Run 是否有任何开销或任何问题?如果您要进行编码,您会在没有 await 和 Task.Run 的情况下调用它吗?请注意,我在 Points 表中有大约 15,000 行,但我在 PhraseId 上有一个索引。
  • 当你从主线程调用(等待)这个时,应该不需要 BeginInvokeOnMainThread()。
  • 最好的解决方案是 App.DB 提供异步方法:删除 Task.Run 并等待 I/O。
  • 你为什么要在那个方法中lock()?
  • 就 BeginInvoke 而言,这取决于您如何称呼它。显示完整的调用堆栈,缩写。顶层应该是一个async void 事件处理程序。下面清扫者的答案是正确的。

标签: c# xamarin xamarin.forms async-await task


【解决方案1】:

我不确定你想做什么,但回答你的问题:

但是我的方法 IncrementPoints 不是异步方法可以吗?

是的,没关系,这也正是Task.Run的目的之一。您可以使用Task.Run 将同步操作转换为可等待的异步操作。所以你应该在 lambda 中放置非异步方法。如果IncrementPoints 是异步的,你就不需要Task.Run,因为你可以这样做:

await IncrementPoints(...);

你的代码应该是这样的:

vm.Points = new String('☆', phrase.Points + pts);

await Task.Run(() =>
{
    App.DB.IncrementPoints(phrase, pts);
    App.DB.IncrementHistory(HIST.Views);
});
await Task.Delay(250);

【讨论】:

    猜你喜欢
    • 2018-05-15
    • 2019-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 1970-01-01
    • 2023-04-06
    • 2021-04-18
    相关资源
    最近更新 更多