希望你能帮我解决这个问题。我是C#多线程编程的初学者。
我正在尝试构建一个程序,使用两个线程在两个文本文件中写入范围1到2000的所有数字。
每个线程都应该写入1到2000之间的数字,这两个文件中没有找到“文件中没有重复的数字”,并且每个线程都不应该写下另一个线程编写的数字。 / p>
最后,如果我们合并两个文件的编号,我们应该有从1到2000的数字
这是我正在尝试的源代码,但在下面的图像中写入循环存在问题
我无法处理两个同步线程的写入过程,我有exception:
从非同步代码块调用对象同步方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace Multithreading
{
class Program
{
static TextWriter file2 = new StreamWriter("file2 location");
static TextWriter file1 = new StreamWriter("file1 location");
static void Main(string[] args)
{
try
{
int[] array = new int[2000];
Thread thread1 = new Thread(Program.writeinfile1);
Thread thread2 = new Thread(Program.writeinfile2);
for (int counter = 1; counter <= 2000; counter++)
{
thread1.Start(counter);
thread2.Start(++counter);
Monitor.Enter(thread1);
Monitor.Wait(thread1);
Monitor.PulseAll(thread2);
}
}
catch (FileNotFoundException)
{
Console.WriteLine("the file you are trying to open is not found");
}
}
public static void writeinfile1(object x)
{
int converttointx = (int)x;
file1.WriteLine(converttointx);
file1.Close();
}
public static void writeinfile2(object y)
{
int converttointy = (int)y;
file2.WriteLine(converttointy);
file2.Close();
}
}
}
答案 0 :(得分:2)
以下是多线程通话的示例,以确保他们不会重复工作。 我没有完全按照你所要求的那样做,因为这看起来很像家庭作业;但希望这可以帮助您找出解决问题的方法......
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace StackOverflow
{
class Program
{
static void Main(string[] args)
{
new Program();
Console.WriteLine("done");
Console.ReadKey();
}
Program()
{
int noThreads = 5;
int target = 2000;
StartThread(noThreads, target);
}
//kicks off our threads / waits for all threads to complete before returning
void StartThread(int noThreads, int target)
{
int id = noThreads--;
if (id > 0)
{
Doer doer = new Doer(id, target);
Thread t = new Thread(doer.Do);
t.Start();
StartThread(noThreads,target);
t.Join();
}
}
}
class Doer
{
static int marker = 0;
static readonly object syncLocker = new object();
readonly int id;
readonly int target;
public Doer(int id, int target)
{
this.id = id;
this.target = target;
}
public void Do()
{
while (marker < this.target)
{
int i;
lock (syncLocker)
{
i = ++marker;
}
System.Console.WriteLine("{0:00}: {1:###0}", id, i);
//Thread.Sleep(RandomNo()); //uncomment this & code below if your threads are taking turns / behaving too predictably
}
}
/*
static readonly Random rnd = new Random();
static readonly object rndSyncLocker = new object();
public static int RandomNo()
{
lock (rndSyncLocker)
{
return rnd.Next(0, 1000);
}
}
*/
}
}
答案 1 :(得分:0)
您没有正确使用Monitor
课程。对Monitor.PulseAll(thread2);
的调用应称为within thread the thread which owns the lock,在这种情况下,该调用将在writeinfile1
和writeinfile2
方法中。
这就是你得到例外的原因:
从非同步代码块调用对象同步方法。
有关使用Monitor.PulseAll(object)
的正确方法,请参阅以下StackOverflow问题: