2

我只是写了下面的代码,我希望在 C# 中有 3 个具有异步功能的文本文件,但我什么也没看到:

  private async void Form1_Load(object sender, EventArgs e)
        {
            Task<int> file1 = test();
            Task<int> file2 = test();
            Task<int> file3 = test();
            int output1 = await file1;
            int output2 = await file2;
            int output3 = await file3;

        }

  async Task<int> test()
        {
            return await Task.Run(() =>
            {
                string content = "";
                for (int i = 0; i < 100000; i++)
                {
                    content += i.ToString();
                }
                System.IO.File.WriteAllText(string.Format(@"c:\test\{0}.txt", new Random().Next(1, 5000)), content);
                return 1;
            });
        }
4

2 回答 2

5

有几个潜在的问题:

  1. c:\test\存在吗?如果没有,你会得到一个错误。
  2. 正如所写,您的Random对象可能会生成相同的数字,因为当前系统时间用作种子,并且您几乎在同一时间执行这些操作。您可以通过让他们共享一个static Random实例来解决此问题。编辑:但您需要以某种方式同步对它的访问lock我在实例上选择了一个简单的Random,这不是最快的,但适用于这个例子。
  3. 以这种方式构建很长的时间string是非常低效的(例如,在调试模式下对我来说大约需要 43 秒,只做一次)。你的任务可能工作得很好,你没有注意到它实际上在做任何事情,因为它需要很长时间才能完成。StringBuilder通过使用类(例如大约 20 毫秒),它可以变得更快。
  4. (这不会影响它是否有效,但更多的是一种风格)你不需要在你的方法中使用asyncandawait关键字。test()它们是多余的,因为Task.Run已经返回 a Task<int>

这对我有用:

private async void Form1_Load(object sender, EventArgs e)
{
    Task<int> file1 = test();
    Task<int> file2 = test();
    Task<int> file3 = test();
    int output1 = await file1;
    int output2 = await file2;
    int output3 = await file3;

}
static Random r = new Random();
Task<int> test()
{
    return Task.Run(() =>
    {
        var content = new StringBuilder();
        for (int i = 0; i < 100000; i++)
        {
            content.Append(i);
        }
        int n;
        lock (r) n = r.Next(1, 5000);
        System.IO.File.WriteAllText(string.Format(@"c:\test\{0}.txt", n), content.ToString());
        return 1;
    });
}
于 2013-10-16T13:36:29.470 回答
2

每次使用不同的Random实例将导致 Random number generation 每次生成相同的数字!

The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated. 

这是因为 Random 使用计算机的时间作为种子值,但其精度不足以满足计算机的处理速度。

使用相同的随机数生成器,例如:

internal async Task<int> test()
{
    return await Task.Run(() =>
    {
        string content = "";
        for (int i = 0; i < 10000; i++)
        {
            content += i.ToString();
        }
        System.IO.File.WriteAllText(string.Format(@"c:\test\{0}.txt",MyRandom.Next(1,5000)), content);
        return 1;
    });
}

编辑:

此外 Random 不是线程安全的,因此您应该同步对它的访问:

public static class MyRandom
{
    private static Random random = new Random();
    public static int Next(int start, int end)
    {
        lock (random)
        {
            return random.Next(start,end);
        }
    }
}
于 2013-10-16T13:34:11.863 回答