需要高效率的设计建议我用例 [英] Need suggestions for efficient design for my use case

查看:113
本文介绍了需要高效率的设计建议我用例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图第三方库在我的WPF应用程序集成。该库由他/她的社会安全号码来收集个人的信用卡记录。它基本上提供了返回void的方法。一旦方法完成后,你可以收集信用卡的历史。

I am trying to integrate a third party library in my WPF application. This library is used to collect credit card history for a person by his/her social security number. It basically provides a method that returns void. Once that method is complete, you can collect credit card history.

ThirdPartyLibrary Instance = new Instance(SSN);
Instance.Run();    // This method returns a void and it blocks until data retrieval completes
if ( Instance.Success )
    CreditHistory History = Instance.CreditHistory;

现在我想同时,但是运行这个API进行的人数,我也想有一次请求的最大数量的阈值。如果阈值被打,我想等待这些请求发送一个新的请求之前完成的。最后,我想提供一个更新我的UI提交请求的任何一个成功或失败。

Now I want to run this API for number of persons simultaneously, however, I also want to have a threshold of maximum number of requests at a time. If that threshold is hit, I would like to wait for one of those request to complete before sending a new request. Finally I would like provide an update my UI as any one of submitted requests succeeds or fails.

下面是我的问题:


  1. 这第三方API可能最终收集的信息等待相当一段时间。使用TPL / PLINQ API,如 Parallel.ForEach 进行AsParallel 很好的候选人这种情况呢?

  1. This third party API may end up waiting for quite sometime for collecting the information. Is using TPL/PLINQ APIs like Parallel.ForEach or AsParallel good candidate for this situation?

我可以使用的await /异步以创建一个包装器调用因为它的run方法返回一个空?第三方库

Can I use await/async to create a wrapper around calls to third party library given that its Run method returns a void?

什么是等待提交,这样我可以保持我的更新对进度UI单独的请求最好的办法。

What would be best approach to wait for individual request submitted so that I can keep updating my UI about the progress.

请提供您的建议(带一些样本code)关于应该如何设计/实施?我一直在做的阅读任务和异步/等待很多,但得到的东西可能是这种使用情况最好的方式很困惑?

Please provide your suggestions (with some sample code) on how it should be designed/implemented? I have been doing lot of reading on Tasks and Async/Await but got quite confused as what could be best patterns for this use case?

推荐答案

作为@ l3arnon指出的那样,你的API是同步的(即使它执行基于O型I /操作,这自然是异步的)。因此,你需要把它当作阻挡。

As @l3arnon pointed out, your API is synchronous (even though it's performing I/O-based operations, which are naturally asynchronous). So, you'll need to treat it as blocking.

不知道更多关于你的要求,我建议异步 Task.Run 。你也可以使用并行或并行LINQ(进行AsParallel ),但他们的工作时,你最好知道操作的总人数在开始,目前还不清楚这是否是此方案中的情况。另外,如果你要添加操作而有些则是在飞行中,你也可以考虑 TPL数据流接收。海事组织,异步办法具有​​最低的学习曲线。然而,接收特别有一个非常优雅的设计,一旦你了解它,你会开始到处使用它。

Without knowing more about your requirements, I'd recommend async with Task.Run. You could also use Parallel or Parallel LINQ (AsParallel), but they work best when you know the total number of operations at the beginning, and it's not clear whether that's the case in this scenario. Also, if you have to add operations while others are in-flight, you could also consider TPL Dataflow and Rx. IMO, the async approach has the lowest learning curve. However, Rx in particular has a very elegant design and once you learn it you'll start using it everywhere.

首先,你可能想使用天然返回类型和异常错误处理的实用方法。我不知道为什么你的第三方类不已经有这样的事情:

First off, you'd probably want a utility method that uses natural return types and exceptions for error handling. I'm not sure why your third-party class doesn't already have something like this:

CreditHistory GetCreditHistory(string ssn)
{
  var instance = new Instance(ssn);
  instance.Run();
  if (instance.Success)
    return instance.CreditHistory;
  throw ...
}

异步情况下,你会开始写一个应该从UI线程调用的方法,并在后台执行的工作:

In the async case, you'd start off writing a method that should be called from the UI thread, and executes the work in the background:

async Task GetCreditHistoryOnBackgroundThreadAsync(string ssn)
{
  try
  {
    var history = await Task.Run(() => GetCreditHistory(ssn));
    // Update UI with credit history.
  }
  catch (Exception ex)
  {
    // Update UI with error details.
  }
}

然后,您可以添加异步节流。这是一种方法,使用内置的 SemaphoreSlim

private readonly SemaphoreSlim _mutex = new SemaphoreSlim(10);
async Task GetCreditHistoryOnBackgroundThreadAsync(string ssn)
{
  await _mutex.WaitAsync();
  try
  {
    var history = await Task.Run(() => GetCreditHistory(ssn));
    // Update UI with credit history.
  }
  catch (Exception ex)
  {
    // Update UI with error details.
  }
  finally
  {
    _mutex.Release();
  }
}

这篇关于需要高效率的设计建议我用例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆