Reputation: 185
I simply wrote below codes and I expect to have 3 text files with async feature in C# but I do not see anything:
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;
});
}
Upvotes: 2
Views: 3220
Reputation: 3118
Using a different Random instance each time will cause the Random number generation to generate the same number each time!
The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated.
This is because Random uses the computer's time as a seed value but the precision of this is not sufficient for the computer's processing speed.
Use the same Random number generator, example:
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;
});
}
EDIT:
Also Random is not thread safe so you should synchronize access to it:
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);
}
}
}
Upvotes: 2
Reputation: 56586
There are a few potential issues:
c:\test\
exist? If not, you'll get an error.Random
objects might generate the same numbers, since the current system time is used as the seed, and you are doing these at about the same time. You can fix this by making them share a static Random
instance. Edit: but you need to synchronize the access to it somehow. I chose a simple lock
on the Random
instance, which isn't the fastest, but works for this example.string
that way is very inefficient (e.g. about 43 seconds in Debug mode for me, to do it once). Your tasks might be working just fine, and you don't notice that it's actually doing anything because it takes so long to finish. It can be made much faster by using the StringBuilder
class (e.g. about 20 ms).async
and await
keywords in your test()
method as written. They are redundant, since Task.Run
already returns a Task<int>
.This works for me:
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;
});
}
Upvotes: 5