2

以下のコードを書いただけで、C# で async 機能を備えた 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は非常に非効率的です (たとえば、デバッグ モードで 1 回実行するのに約 43 秒かかります)。タスクは正常に機能している可能性がありますが、完了までに時間がかかりすぎるため、実際に何かを実行していることに気付かないことがあります。クラスを使用すると、さらに高速化できますStringBuilder(例: 約 20 ms)。
  4. (これは動作するかどうかには影響しませんが、より文体的なものです)書かれているように、メソッドでasyncandawaitキーワードを使用する必要はありません。すでに a を返すためtest()、これらは冗長です。Task.RunTask<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インスタンスを使用すると、乱数生成で毎回同じ数が生成されます。

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

これは、ランダムがコンピューターの時間をシード値として使用するためですが、この精度はコンピューターの処理速度に対して十分ではありません。

同じ乱数ジェネレーターを使用します。例:

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;
    });
}

編集:

また、ランダムはスレッドセーフではないため、アクセスを同期する必要があります。

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 に答える