简体   繁体   English

在.net中管理异步任务

[英]Managing async tasks in .net

I am creating program to download some files. 我正在创建程序来下载一些文件。 I am testing the async methods and I have problem. 我正在测试异步方法,但是有问题。 I want to set limit one the amount of downloaded files. 我想将下载文件的数量限制为一个。 I have static method: 我有静态方法:

public static async Task StreamToFile(Stream input, string fileName)
    {
        if (input != null)
        {
            string dir = Path.GetDirectoryName(fileName);
            if (!Directory.Exists(dir))
                Directory.CreateDirectory(dir);
            using (Stream str = File.Create(fileName))
            {
                await input.CopyToAsync(str);
                input.Dispose();
            }
        }
    }

Stream is created outside. 流是在外部创建的。 And now, I want to call this method for example 10 times, then application should wait for completing any of running task and start new one. 现在,我想调用此方法例如10次,然后应用程序应等待完成任何正在运行的任务并开始新的任务。 I don't want to wait for all ten tasks, I want to start new immediately after one of the tasks close. 我不想等待所有十个任务,我想在其中一项任务关闭后立即开始新的任务。 How can I manage tasks? 如何管理任务? In Threads I was able to create old school List with threads, set while loop 在Threads中,我能够创建带有线程的旧学校列表,并在while循环中设置

while(ListOfThreads.Count >=Limit)
{
    for(int i=0;i<ListOfThreads.Count;i++)
    {
        if (ListOfThreads[i].IsCompleted)
        {
            ListOfThreads.RemoveAt(i);
            i--;
        }
    }
}

but when I try to do the same with Tasks program stucks and never reaches input.Dispose() in StreamToFile. 但是当我尝试对Tasks程序执行相同的操作时,却永远无法在StreamToFile中到达input.Dispose()。 Tasks have WaitingForActivation status. 任务的状态为WaitingForActivation。

When I remove loop everything works fine but of course program are downloading all links that I paste 当我删除循环时,一切正常,但是程序当然会下载我粘贴的所有链接

SemaphoreSlim can be used to throttle asynchronous operations: SemaphoreSlim可用于限制异步操作​​:

private static SemaphoreSlim mutex = new SemaphoreSlim(10);
public static async Task StreamToFile(Stream input, string fileName)
{
  await mutex.WaitAsync();
  try
  {
    if (input != null)
    {
      string dir = Path.GetDirectoryName(fileName);
      if (!Directory.Exists(dir))
        Directory.CreateDirectory(dir);
      using (Stream str = File.Create(fileName))
      {
        await input.CopyToAsync(str);
        input.Dispose();
      }
    }
  }
  finally
  {
    mutex.Release();
  }
}

I looked it for 3 hours but after posting question I found solution: https://msdn.microsoft.com/pl-pl/library/JJ155756.aspx 我看了3个小时,但在发布问题后找到了解决方案: https : //msdn.microsoft.com/pl-pl/library/JJ155756.aspx

I have to create list of tasks 我必须创建任务列表

List<Task> tasksList= new List<Task>();

and check if it reaches the limit 并检查是否达到极限

if(tasksList.Count>=limit)
{
    var firstFinished= await Task.WhenAny(tasksList);
    tasksList.Remove(firstFinished);
}

then Add of course task 然后添加课程任务

tasksList.Add(AsyncMethod(parameters));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM