Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使文件下载线程安全_C#_.net_Multithreading_Thread Safety - Fatal编程技术网

C# 使文件下载线程安全

C# 使文件下载线程安全,c#,.net,multithreading,thread-safety,C#,.net,Multithreading,Thread Safety,我有一个场景,我必须从api调用中获取客户的xml文件,然后在第一次请求时将其保存在我的计算机中,然后该客户的每个请求都将使用我的计算机文件来获取特定客户的数据 例如,如果我有两个客户ABC和XYZ。假设第一个请求来自ABC,我想开始下载ABC的文件。在下载过程中,假设XYZ的第一个请求出现。我还想继续下载XYZ客户文件。但是,让我们说,当下载正在进行的ABC和另一个ABC的要求来了,我应该让它等待,直到ABC的文件下载后,文件将被下载,我想从该文件获得第二次请求的数据 如果我锁定下载代码,我想

我有一个场景,我必须从api调用中获取客户的xml文件,然后在第一次请求时将其保存在我的计算机中,然后该客户的每个请求都将使用我的计算机文件来获取特定客户的数据

例如,如果我有两个客户ABC和XYZ。假设第一个请求来自ABC,我想开始下载ABC的文件。在下载过程中,假设XYZ的第一个请求出现。我还想继续下载XYZ客户文件。但是,让我们说,当下载正在进行的ABC和另一个ABC的要求来了,我应该让它等待,直到ABC的文件下载后,文件将被下载,我想从该文件获得第二次请求的数据

如果我锁定下载代码,我想有两种解决方案

// code
lock(obj)
{
   DownloadXmle("ABC");
}
// code
第二个选项是,如果我声明了一个静态列表,在下载文件之前,我将客户号推到该列表中,对于该客户的所有其他请求,它将检查机构号是否在该列表中,它应该等待

//code
currentlyDownloadingFileList.add("ABC");
 DownloadXmle("ABC");
currentlyDownloadingFileList.Remove("ABC");
//code

有更好的方法吗?

您应该使用
ConcurrentDictionary
来存储线程安全的客户地图,以锁定对象


使用
GetOrAdd()
为客户安全地获取锁定对象,然后锁定该对象。

您应该使用
ConcurrentDictionary
存储客户的线程安全映射以锁定对象


使用
GetOrAdd()
为客户安全地获取一个锁对象,然后锁定该对象。

在我看来,使用TPL更好
DownloadXmle
应该是异步方法,返回
Task
或只是
Task
。它将帮助您更好地利用资源,并为您的任务提供强大的工具。让我们看看这种情况下的方法实现:

public async Task DownloadXmleAsync(string customer)
{
...
}
下一步调用方法时,应将返回的任务保存在某个位置:

Task taskAbc = DownloadXmleAsync("ABC");
当您收到此客户的新请求时,您应执行以下操作:

taskAbc = taskAbc.ContinueWith(prevTask => DownloadXmleAsync("ABC"));

ContinueWith将安排您的下一个呼叫,并仅在第一个请求完成后运行。第二个任务将在任何情况下运行<代码>任务ABC将是指向第二个任务的链接。每次您收到新请求时,它都会被安排。

在我看来,使用TPL更好
DownloadXmle
应该是异步方法,返回
Task
或只是
Task
。它将帮助您更好地利用资源,并为您的任务提供强大的工具。让我们看看这种情况下的方法实现:

public async Task DownloadXmleAsync(string customer)
{
...
}
下一步调用方法时,应将返回的任务保存在某个位置:

Task taskAbc = DownloadXmleAsync("ABC");
当您收到此客户的新请求时,您应执行以下操作:

taskAbc = taskAbc.ContinueWith(prevTask => DownloadXmleAsync("ABC"));

ContinueWith将安排您的下一个呼叫,并仅在第一个请求完成后运行。第二个任务将在任何情况下运行<代码>任务ABC将是指向第二个任务的链接。每次您收到新请求时,它都会被安排。

列表不是线程安全的。@如果我锁定ABC的下载操作,我也将无法为XYZ下载。您可能希望维护记录,记录哪个客户端正在下载哪个文件,或者如果客户端已在下载某个文件,则列表不是线程安全的。@SLaks如果我锁定,则会锁定ABC的下载操作我也无法为XYZ下载您可能需要维护哪个客户端正在下载哪个文件的记录,或者如果客户端已经在下载某个文件