用task实现多窗口售票——
代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using System.IO; using System.Reflection; using System.Diagnostics; namespace SellTicketsSynchronously { class Program { //入口 static void Main(string[] args) { Ticket tc = new Ticket(10); Task t1 = new Task(() => { CallWithAsync(tc); }); t1.ContinueWith(t => { Console.WriteLine("Tickets has been sold out. Press any key to quit:"); }); t1.Start(); Console.ReadLine(); } //调用异步方法 private static void CallWithAsync(Ticket tc) { Task.Run(() => { Task.Run(() => { SellTicket("Window1", tc); }); Task.Run(() => { SellTicket("Window2", tc); }); Task.Run(() => { SellTicket("Window3", tc); }); Task.Run(() => { SellTicket("Window4", tc); }); }); } //卖票方法 public static void SellTicket(string windowName, object obj) { string nameOfWindow = windowName; Ticket ticket = obj as Ticket; while (ticket.NumOfTickets > 0) { lock (ticket) { if (ticket.NumOfTickets > 0) { try { ticket.NumOfTickets--; Console.WriteLine(DateTime.Now.ToString() + ":" + nameOfWindow + " sells a ticket, " + ticket.NumOfTickets + " tickets left."); } catch (Exception ex) { WriteLog(ex); } } } Random random = new Random(); Thread.Sleep(random.Next(100,500)); } } //打log方法 private static void WriteLog(Exception ex) { string logUrl = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\SellTicketslog.txt"; if (File.Exists(@logUrl)) { using (FileStream fs = new FileStream(logUrl, FileMode.Append)) { using (StreamWriter sw = new StreamWriter(fs, Encoding.Default)) { try { sw.Write(ex); } catch (Exception ex1) { WriteLog(ex1); } finally { sw.Close(); fs.Close(); } } } } else { using (FileStream fs = new FileStream(logUrl, FileMode.CreateNew)) { using (StreamWriter sw = new StreamWriter(fs, Encoding.Default)) { try { sw.Write(ex); } catch (Exception ex1) { WriteLog(ex1); } finally { sw.Close(); fs.Close(); } } } } } } //票类 class Ticket { public int NumOfTickets { get; set; } public Ticket(int num) { this.NumOfTickets = num; } } }
运行结果:
应该怎么办呢?我明明用了ContinueWith方法了,但是没有效果。
另:如果有更好的思路请给段代码学习学习。 :)
因为这里的 Task 一闪而过,不会像你认为的会等到四个 Task 完成后才返回。
Task.Run(() =>
{
Task.Run(() => { SellTicket("Window1", tc); });
Task.Run(() => { SellTicket("Window2", tc); });
Task.Run(() => { SellTicket("Window3", tc); });
Task.Run(() => { SellTicket("Window4", tc); });
});
我把这个方法调用放在一个task里,然后task.ContinueWith不是应该在这个task执行完毕之后才执行ContinueWith中的内容吗?
应该怎么修改呢?
@天外归云: 你的 t1 是在 t1 执行完 CallWithAsync 后才执行 ContinueWith 中的内容的。
@天外归云:
List<Task> tasks = new List<Task>();
for(int i=0;i<4;i++)
tasks.Add(Task.Run(() => { SellTicket(string.Format("Window{0}",i), tc); }));
Task.WaitAll(tasks.ToArray());
@Launcher: 非常感谢!已经改好了!
@Launcher:
//入口
static void Main(string[] args)
{
Ticket tc = new Ticket(10);
CallWithAsync(tc);
Console.WriteLine("Tickets has been sold out. Press any key to quit:");
Console.ReadLine();
}
//调用异步方法
private static void CallWithAsync(Ticket tc)
{
List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(() => { SellTicket("Window1", tc); }));
tasks.Add(Task.Run(() => { SellTicket("Window2", tc); }));
tasks.Add(Task.Run(() => { SellTicket("Window3", tc); }));
tasks.Add(Task.Run(() => { SellTicket("Window4", tc); }));
Task.WaitAll(tasks.ToArray());
}
Task.WaitAll(task);
task.start();
已经改好啦:
//入口
static void Main(string[] args)
{
Ticket tc = new Ticket(10);
CallWithAsync(tc);
Console.WriteLine("Tickets has been sold out. Press any key to quit:");
Console.ReadLine();
}
//调用异步方法
private static void CallWithAsync(Ticket tc)
{
List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(() => { SellTicket("Window1", tc); }));
tasks.Add(Task.Run(() => { SellTicket("Window2", tc); }));
tasks.Add(Task.Run(() => { SellTicket("Window3", tc); }));
tasks.Add(Task.Run(() => { SellTicket("Window4", tc); }));
Task.WaitAll(tasks.ToArray());
}
这种就是典型的你在逗我l。。
你自己都知道外面的异步任务要等待才行,为什么里面的异步的任务就不用等待?
改好啦:
//入口
static void Main(string[] args)
{
Ticket tc = new Ticket(10);
CallWithAsync(tc);
Console.WriteLine("Tickets has been sold out. Press any key to quit:");
Console.ReadLine();
}
//调用异步方法
private static void CallWithAsync(Ticket tc)
{
List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(() => { SellTicket("Window1", tc); }));
tasks.Add(Task.Run(() => { SellTicket("Window2", tc); }));
tasks.Add(Task.Run(() => { SellTicket("Window3", tc); }));
tasks.Add(Task.Run(() => { SellTicket("Window4", tc); }));
Task.WaitAll(tasks.ToArray());
}