使用c#在后台线程中调用函数

时间:2017-01-10 11:56:17

标签: c# async-await task

我有一个函数Init(),其中有许多函数正在调用Product类。但是有一个函数“UpdateProduct()”有大约3000行的大量记录,并且由于这个Init()函数需要花费太多时间来执行。所以为了提高性能,我想调用UpdateProduct()函数应该是Async。为此,我想使用Async& amp;等待。我试图这样做,但能够做到这一点。所以任何人都可以为此提出建议。请查看以下内容 -

Public Int Init()
{
    Product p = new Product();
    Int productId = 10;
    Int UserId  = 101;

    Int count = 4;

    if(count > 0)
    {
        var result = p.XYZ();
    }

    if(count > 0)
    {
        var result = p.ABC();
    }

    if(count > 0)
    {
        var result = p.MNC();
    }

    if(count > 0)
    {
        var result = p.UpdateProduct(productId,UserId);
    }

    ------------etc (other stuff)------
}

请查看下面的产品类 -

public class Product
{
      public void UpdateProduct(int productId,int UserId)
      {
          Category cat = new Category();

          var catList = cat.GetCategory();

          for(int i=0; i< catList.count; i++)  //there are 3000 records here
          {
             --------------some process--------
             --------------- --------
          }
      }

}

仅供参考,我希望UpdateProduct方法应该在后台调用,直到其他功能应该执行,并且一旦完成所有其他功能就应该等待(等待)。

4 个答案:

答案 0 :(得分:1)

如果您想使用async-await方法,则需要准备好将所有相关方法从UI更改为数据访问。

首先将UpdateProduct更改为异步(向方法添加后缀Async

public class Product
{
    public async Task UpdateProductAsync(int productId,int UserId)
    {
        Category cat = new Category();

        // this need to be changed to async too
        var categories = await cat.GetCategoryAsync(); 

        foreach(var category in categories)
        {
            // process result of GetCategoryAsync
        }
    }
}

然后Init方法也需要更改为异步。因为方法返回int返回类型将为Task<int>

Public async Task<int> InitAsync()
{
   Product p = new Product();
   int productId = 10;
   int UserId  = 101;

   int count = 4;

   // .. execute all methods before UpdateProduct

    if(count > 0)
    {
        var result = await p.UpdateProductAsync(productId,UserId);
    }

    // execute all methods after Updateproduct

    return result;
}

当然,使用InitAsync的方法需要更改为“支持”异步。

使用上面的方法,您将使用“正确”async-await方法,该方法仅使用一个线程,并在等待响应时释放UI线程。
请注意,此方法主要用于处理IO设备,如文件,Web服务,数据库。

另一方面,你可以用另一个线程包装同步UpdateProduct方法并等待它完成。这个解决方案可行,但不会像以前那样有效,因为它会使用一个不做任何事情的额外线程 - 只等待响应。

另一种情况 - 如果你的瓶颈是类别处理

var categories = await cat.GetCategory(); 

foreach(var category in categories)
{
    // heavy-long calculation
}

在这种情况下,最好使用并行方法,有效地使用用户的计算机核心。

var categories = await cat.GetCategoryAsync().ToList(); 
Parallel.ForEach(categories, Calculate);

private sub Calculate(Category category)
{
    // Do your calculation
}

答案 1 :(得分:0)

Public async Int Init()
{
    Product p = new Product();
    Int productId = 10;
    Int UserId  = 101;

    Int count = 4;

    if(count > 0)
    {
        var result = p.XYZ();
    }

    if(count > 0)
    {
        var result = p.ABC();
    }

    if(count > 0)
    {
        var result = p.MNC();
    }

    if(count > 0)
    {
         await p.UpdateProduct(productId,UserId);
    }

    ------------etc (other stuff)------
}

public class Product
{
      public Task UpdateProduct(int productId,int UserId)
      {
          Category cat = new Category();

          var catList = cat.GetCategory();

          for(int i=0; i< catList.count; i++)  //there are 3000 records here
          {
             --------------some process--------
             --------------- --------
          }
      }

}

答案 2 :(得分:0)

尝试此代码我希望此代码可以帮助您

创建方法

SELECT * FROM `Movies` WHERE `movie_Date` BETWEEN $date1 AND $date2;

致电

public Task<string> TestMethod()
{
    TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
     //your code Here
    return tcs.Task;
}

答案 3 :(得分:0)

c_list

然后你的Init方法看起来像这样(请注意,当UpdateProduct正在执行时,其他方法将执行)

public class Product
{
    public async Task UpdateProduct(int productId, int UserId)
    {
        await Task.Run(() =>
        {
            //this will simulate your process
            Thread.Sleep(10000);

            //Category cat = new Category();

            //var catList = cat.GetCategory();

            //for (int i = 0; i < catList.count; i++)  //there are 3000 records here
            //{
            //    --------------some process--------
            //    -------------- - --------
            //}
        });            
    }

    public int XYZ()
    {
        return 1;
    }

    public int ABC()
    {
        return 1;
    }

    public int MNC()
    {
        return 1;
    }
}