【问题标题】:WebApi: how to make async methods run first, before going onWebApi:如何让异步方法先运行,然后再继续
【发布时间】:2021-01-20 18:53:58
【问题描述】:

我正在尝试操作网页上的数据,我有一个 API 可以做到这一点,但我遇到了一些问题。

在我的代码中有一部分,我在其中插入、操作然后将数据更新到网页。 API 使用异步方法向网页插入和更新数据,所以我无法更改。

这是出现问题的代码:

namespace Web
{
    class WebDatabase
    {
        WebApi api;

        internal static async Task InsertCategory(string category)
        {
            await api.Insert(category);  //  Insert data to the database
            //Some manipulation on the category
            //..
            //..
            await api.GetCategoryIdFromDatabase(category);  //  Getting id of data from the database
            await api.Update(category);   //  Updating that data based on id in the database
        }
    }
}

如您所见,在将数据插入数据库后,我必须从数据库中获取自动生成的 ID,以便能够更新我操作的数据,但有时它会在尝试获取数据之前将其插入身份证,有时没有! 我该如何解决?我一定是做错了什么,但我想我想尽一切办法让它工作,但仍然没有成功:(

这是剩下的代码,也许它会帮助你更好地了解发生了什么。


主要

namespace Main
{
    class Program
    {
        Thread thread;

        private void buttonClick(object sender, EventArgs e)
        {
            if (thread != null && thread.IsAlive)
            {
                Console.WriteLine("The process is still going!");
                return;
            }

            thread = new Thread(Send);
            thread.Start();
        }

        private async void Send()
        {
            await WebDatabase.SendCategoryList(category);
        }
    }
}

网络数据库

namespace Web
{
    class WebDatabase
    {
        WebApi api;

        internal static async Task SendCategoryList(string category)
        {
            await api.Insert(category);   //   Inserting data to the database
            //Some manipulation on the category
            //..
            //..
            //   
            await api.GetCategoryIdFromDatabase(category);    //  Trying to get ID from database, but the data is not there yet, so it throws an error
            await api.Update(category);   //  Now I can't update my poor category in the database :(
        }
    }
}

API

namespace API
{
    class WebApi
    {
        WebAPI webapi = new WebAPI();

        public async Task Insert(List<string> categoriesList)
        {
            for (int i = 0; i < categoriesList.Count; i++)
            {
                await Update(categoriesList[i]);
            }
        }

        public async Task Update(string categories)
        {
            await webapi.Category.Add(categories);
        }

        public async Task GetCategoryIdFromDatabase(string categories)
        {
            await webapi.Category.GetAll().Result.FirstOrDefault(productCategory => productCategory.name.Trim().ToLower() == category.name.Trim().ToLower()).id.Value;
        }
    }
}

任何帮助将不胜感激!

【问题讨论】:

  • 看看这个:Is it ok to use “async” with a ThreadStart method? 简而言之,Thread 构造函数不是异步友好的。传递的方法(Send)是async void,也就是something to avoid
  • @TheodorZoulias 感谢您的提示!我将thread = new Thread(Send);thread.Start(); 行更改为await Task.Run(Send);,但现在我在更新方法中遇到异常,说我的API 连接无效......也许它与我从数据库?我将更新问题以展示它如何为我工作
  • @TheodorZoulias 我更新了 GetCategoryIdFromDatabase 部分!
  • @MartinSerdült 在处理任务时使用原始线程毫无意义。 async void 仅适用于事件处理程序。您应该使用async Task Main()根本不使用线程,将Send 更改为async Task Send 并从Mainawait Send() 调用它
  • 至于GetCategoryIdFromDatabase 看起来您使用了“通用”存储库antipattern,在使用webapi.Category.GetAll().Result 阻塞时将整个表加载到内存中,然后尝试过滤-记忆结果。 DbContext 是比存储库更高级别的抽象。您可以使用 var category=await dbContext.Categories.Where(cat=&gt;cat.name==category.name).Select(cat=&gt;cat.Id).FirstOrDefaultAsync(); 异步加载您想要的内容

标签: c# database asynchronous woocommerce webapi


【解决方案1】:

切勿将async void 用于任何方法。而是使用async Task&lt;bool&gt;async Task&lt;int&gt;

当您使用async void 时,可能会正确捕获抛出的异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-23
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多