作为一个做线程和任务的新手,我在我的小练习应用程序中编写了两个线程和一个任务,如下所示:
static List<string> myList = new List<string>(); static void Main(string[] args) { //Run the whole operation both threads and task. Operation(); } static async void Operation() { Task t = Task.Run(new Action(RunThreads)); t.Wait(); //Write the result. WriteMessage(); } static void RunThreads() { //Read thread1. string threadName = "Thread-1"; Thread thread1 = new Thread(() => DoSomething(threadName)); thread1.Name = threadName; thread1.Start(); //Read thread2. threadName = "Thread-2"; Thread thread2 = new Thread(() => DoSomething(threadName)); thread2.Name = threadName; thread2.Start(); } public static void DoSomething(string threadName) { for (int i = 1; i < 10; i++) { myList.Add(string.Format("{0} from thread: {1}", i, threadName)); } } private static void WriteMessage() { foreach (string val in myList) { Console.WriteLine(val); } Console.Read(); }
我希望首先完全执行两个线程,并在&#34; myList&#34;中添加值。一旦这些线程完成(最终在这两个线程结束时,&#34; myList&#34;将包含20个项目......)然后运行&#34; WriteMessage()&#34;循环遍历所有这20个项目并在控制台中打印它们的方法。
以下是我期望在控制台中编写的输出:
(我知道来自&#34; Thread-1&#34;和&#34; Thread-2&#34;的消息序列可能不同,因为该过程将是异步的但应该恰好10每个项目。)
我的实现问题是:在完成这两个线程之前,正在执行WriteMessage()方法。
答案 0 :(得分:0)
static object _lock = new object();
static List<string> myList = new List<string>();
TaskFactory TaskFac = new TaskFactory();
static void Main(string[] args)
{
//Run the whole operation both threads and task.
Operation();
}
static async void Operation()
{
Task t = Task.Run(new Action(RunThreads)).ContinueWith(o => {
WriteMessage();
});
t.Wait();
Console.ReadKey();
//Write the result.
// WriteMessage();
}
static void RunThreads()
{
//Read thread1.
string threadName = "Thread-1";
Thread thread1 = new Thread(() =>
{
for (int i = 1; i < 11; i++)
{
DoSomething(
threadName, i
);
}
});
thread1.Start();
string threadName1 = "Thread-2";
Thread thread2 = new Thread(() => {
for (int i = 1; i < 11; i++)
{
DoSomething(
threadName1, i
);
} });
thread2.Start();
}
public static void DoSomething(string threadName,int loop_index)
{
Monitor.Enter(_lock);
{
myList.Add(string.Format("{0} from thread: {1}",loop_index, threadName));
Monitor.Exit(_lock);
}
}
private static void WriteMessage()
{
foreach (string val in myList)
{
Console.WriteLine(val);
}
Console.Read();
}
答案 1 :(得分:0)
我认为你要做的是让Operation
void等到另外两个线程完成。我所做的是创建一个布尔值,当线程完成时它将变为true,因此让Operation
继续。这适用于VS2017。在第2行,你可以看到bool,第17行是它等待的地方,第33行是布尔值被改变的地方。我目前不在我的桌面上(笔记本电脑,慢速),所以如果你有进一步的问题,我可以修改这个答案。
static List<string> myList = new List<string>();
static bool taskDone = false;
static void Main(string[] args)
{
//Run the whole operation both threads and task.
Operation();
}
static async void Operation()
{
Task t = Task.Run(new Action(RunThreads));
t.Wait();
//Write the result.
while(!taskDone);
WriteMessage();
}
static void RunThreads()
{
//Read thread1.
string threadName = "Thread-1";
Thread thread1 = new Thread(() => DoSomething(threadName));
thread1.Name = threadName;
thread1.Start();
//Read thread2.
threadName = "Thread-2";
Thread thread2 = new Thread(() => DoSomething(threadName));
thread2.Name = threadName;
thread2.Start();
taskDone = true;
}
public static void DoSomething(string threadName)
{
for (int i = 1; i < 10; i++)
{
myList.Add(string.Format("{0} from thread: {1}", i, threadName));
}
}
private static void WriteMessage()
{
foreach (string val in myList)
{
Console.WriteLine(val);
}
Console.Read();
}
答案 2 :(得分:0)
您可以使用Task来实现此目的。找到下面提供的代码。传递给DoWork函数的参数是执行工作的参数。这应该从每个DoWork调用的循环动态设置。
int numberOfProcess = 3;
Task[] _tasks = new Task[numberOfProcess];
for (int i = 1; i <= numberOfProcess; i++)
{
string[] args = new string[2];
args[0] = minSlNo.ToString();
args[1] = nextSlno.ToString();
_tasks[i - 1] = Task.Factory.StartNew(() =>
{
//do the required work
DoWork(args);
});
System.Console.WriteLine("Min =" + minSlNo + " Next Msg=" + nextSlno);
SetLogFilesProperty("BatchJob_Start", args[0].ToString() + "_" + args[1].ToString());
}
while (_tasks.Any(t => !t.IsCompleted))
{//execution waits till all the tasks are completed
}
Console.Write("All Tasks Completed"+DateTime.Now);