c#async任务 - 根据其顺序为每个任务分配一个INT

发布于 2025-02-12 06:11:21 字数 989 浏览 0 评论 0原文

程序删除两个大型ZIP文件(如果存在),下载新的zip 每个任务都会在触发任务时打印任务的描述要安装。

现在,我还想将编号与描述 - 每次完成任何任务完成时要增加1个数字。

为此,我已经在主方法int x = 1;中声明了变量。 我完成了返回int的所有任务。
task< int>返回整数x1递增。 (返回++ X;)

static async Task Main(string[] args)
{
     string sZip = @" some path ";
     string fZip = @" some path ";
     string sFolder = @" some path ";
     string fFolder = @" some path ";

     int x = 1;

     // Tasks to do
     x = await FirstZipDelete(x, sZip); 

     var sequence2 = new List<Task> { FirstZipDownload(x, sZip), SecondZipDelete(x, fZip) };
     await Task.WhenAll(sequence2); 

     var sequence3 = new List<Task> { SecondZipDownload(x, fZip), 
     FirstZipExtract(x, sZip, sFolder) };
     await Task.WhenAll(sequence3); 

     x = await SecondZipExtract(x, fZip, fFolder);

通过将X =放置在我实现整数增加的单个任务之前。
但是不能应用于并行任务。

解决这个问题的想法吗?

Program deletes two large zip files if exists, download new zips and finally extract it with some tasks done parallelly.
Each task prints description of the task to console when the task is triggered.

Now I also want to print number together with description - number to be incremented by 1 each time any of the tasks is completed.

For this I have declared variable in the main method int x = 1;
I made every task to return a int.
Task<int> returns integer x incremented by 1. ( Return ++x; )

static async Task Main(string[] args)
{
     string sZip = @" some path ";
     string fZip = @" some path ";
     string sFolder = @" some path ";
     string fFolder = @" some path ";

     int x = 1;

     // Tasks to do
     x = await FirstZipDelete(x, sZip); 

     var sequence2 = new List<Task> { FirstZipDownload(x, sZip), SecondZipDelete(x, fZip) };
     await Task.WhenAll(sequence2); 

     var sequence3 = new List<Task> { SecondZipDownload(x, fZip), 
     FirstZipExtract(x, sZip, sFolder) };
     await Task.WhenAll(sequence3); 

     x = await SecondZipExtract(x, fZip, fFolder);

By putting x = before single tasks I achieved incrementing of the integer.
But same could not be applied for parallel tasks.

Any idea to solve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

据我了解,您首先删除旧文件,然后下载和提取。如果删除/下载/提取始终是一个文件的顺序。您应该把它们纳入一项任务。

您遇到的一个问题是X不是螺纹保护,因此您有时会看到序列并不完美。

您需要锁定X,我使用了Interlocked.increment()

我不知道我是否理解“现在,我也想将数字与描述一起打印 - 每次完成任何任务时要增加1个数字。” 正确地。由于我的解决方案结合了一些“任务”。诀窍是使用Interlocked.Increment返回的返回值返回到捕获的增量值。您不会以这种方式误解任何数字,因为增加/存储(因此返回该增量值)是原子。

类似:

string sZip = @" some path ";
string fZip = @" some path ";
string sFolder = @" some path ";
string fFolder = @" some path ";

var tasks = new List<Task>();

// You should start at -1 (because I increment it before the task was executed)
int x = -1;

tasks.Add(Task.Run(async () =>
{
    int xValue = Interlocked.Increment(ref x);
    await FirstZipDelete(xValue, sZip);

    xValue = Interlocked.Increment(ref x);
    await FirstZipDownload(xValue, sZip);

    xValue = Interlocked.Increment(ref x);
    await FirstZipExtract(xValue, sZip, sFolder);
}));

tasks.Add(Task.Run(async () =>
{
    int xValue = Interlocked.Increment(ref x);
    await FirstZipDelete(xValue, fZip);

    xValue = Interlocked.Increment(ref x);
    await FirstZipDownload(xValue, fZip);

    xValue = Interlocked.Increment(ref x);
    await FirstZipExtract(xValue, fZip, fFolder);
}));

await Task.WhenAll(tasks);

一些小的修改,看起来像这样:

string sZip = @" some path ";
string fZip = @" some path ";
string sFolder = @" some path ";
string fFolder = @" some path ";

var tasks = new List<Task>();

int x = 0;

async Task DownloadAndExtract(string zip, string folder)
{
    int xValue = Interlocked.Increment(ref x);
    await FirstZipDelete(xValue, zip);

    xValue = Interlocked.Increment(ref x);
    await FirstZipDownload(xValue, zip);

    xValue = Interlocked.Increment(ref x);
    await FirstZipExtract(xValue, zip, folder);
}

await Task.WhenAll(
    DownloadAndExtract(sZip, sFolder),
    DownloadAndExtract(fZip, fFolder));

As I understand is that you first delete the old file, then download and extract. If the deletion/download/extract are always sequential for one file. You should put them into one task.

A problem you have is that the x is not threadsafe, so you would sometimes see that the sequence is not perfect.

You need to lock x, I've used the Interlocked.Increment() for this.

I don't know if I understand the "Now I also want to print number together with description - number to be incremented by 1 each time any of the tasks is completed." correctly. As my solution combines some "tasks". The trick is to use the return value which Interlocked.Increment returns to captured the incremented value. You won't mis any numbers this way, because incrementing/storing (and so return that incremented value) is atomic.

Something like:

string sZip = @" some path ";
string fZip = @" some path ";
string sFolder = @" some path ";
string fFolder = @" some path ";

var tasks = new List<Task>();

// You should start at -1 (because I increment it before the task was executed)
int x = -1;

tasks.Add(Task.Run(async () =>
{
    int xValue = Interlocked.Increment(ref x);
    await FirstZipDelete(xValue, sZip);

    xValue = Interlocked.Increment(ref x);
    await FirstZipDownload(xValue, sZip);

    xValue = Interlocked.Increment(ref x);
    await FirstZipExtract(xValue, sZip, sFolder);
}));

tasks.Add(Task.Run(async () =>
{
    int xValue = Interlocked.Increment(ref x);
    await FirstZipDelete(xValue, fZip);

    xValue = Interlocked.Increment(ref x);
    await FirstZipDownload(xValue, fZip);

    xValue = Interlocked.Increment(ref x);
    await FirstZipExtract(xValue, fZip, fFolder);
}));

await Task.WhenAll(tasks);

Some small modifications and it might look like this:

string sZip = @" some path ";
string fZip = @" some path ";
string sFolder = @" some path ";
string fFolder = @" some path ";

var tasks = new List<Task>();

int x = 0;

async Task DownloadAndExtract(string zip, string folder)
{
    int xValue = Interlocked.Increment(ref x);
    await FirstZipDelete(xValue, zip);

    xValue = Interlocked.Increment(ref x);
    await FirstZipDownload(xValue, zip);

    xValue = Interlocked.Increment(ref x);
    await FirstZipExtract(xValue, zip, folder);
}

await Task.WhenAll(
    DownloadAndExtract(sZip, sFolder),
    DownloadAndExtract(fZip, fFolder));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文