怎么从外部取消一个await Task.Delay操作?
protected async void Page_Load(object sender, EventArgs e)
{
Task t1 = doSomeThing1();
Task t2 = doSomeThing2();
Cache["t2"] = t2;
Task[] ts = new Task[] { t1, t2 };
await (Task.WhenAll(ts)).ContinueWith<Task>(ResponseW);
}
private async Task doSomeThing2(int time = 1000000)
{
int x = 0;
for (int i = 0; i < time; i++)
{
if (Cache["t1tot2"] == null)
{
await Task.Delay(10000);
continue;
}
if (Cache["t1tot2"] != null)
{
x = (int)Cache["t1tot2"] + 88;
Cache["x"] = x;
return;
}
}
}
private async Task doSomeThing1()
{
await Task.Delay(200);
Cache["t1tot2"] = 10;
}
想在t1里控制t2从await Task.Delay中醒来。。。现在等于是在让t2自己不停的重新检查交换变量,这样太没效率了,谁知道具体怎么办?另外整个过程都要是异步的 否则就没有意义了
using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Web; using System.Web.Caching; using System.Web.UI; using System.Web.UI.WebControls; namespace WebApplication2 { public partial class WebForm1 : System.Web.UI.Page { public static ManualResetEvent flag = new ManualResetEvent(false); protected void Page_Load(object sender, EventArgs e) { Task t1 = doSomeThing1(); Task t2 = doSomeThing2(); flag.Reset(); Task[] ts = new Task[] { t1, t2 }; Task.WhenAll(ts); Console.ReadKey(); } private async Task doSomeThing2(int time = 1000000) { await Task.Run(() => { if (flag.WaitOne(3000)) { int x = (int)Cache["t1tot2"] + 88; Cache["x"] = x; return; } }); } private async Task doSomeThing1() { await Task.Delay(200); flag.Set(); Cache["t1tot2"] = 10; Console.WriteLine("任务一完成了"); } } }
田兄的这ManualResetEvent WaitOne还是同步等待 跟delay没法比
如果要整这个 我自己也有不少办法
flag.WaitOne(3000)的时候 Task。Run的这个线程在运行
我要求该线程也被delay那样的挂起
否则同步等待毫无意义
我的场景中 请求行为希望相关线程都被挂起 释放回线程池 而不是另外开一个线程去等待
如果那么简单 我就不会贴了 。。我也是10来年的开发了
private HttpContext hc;
private CancellationTokenSource source = new CancellationTokenSource();
protected async void Page_Load(object sender, EventArgs e)
{
HttpContext.Current.Response.Clear();
hc = HttpContext.Current;
Task t1 = doSomeThing1();
Task t2 = doSomeThing2();
Cache["t2"] = t2;
Task[] ts = new Task[] { t1, t2 };
Task t3 = (Task.WhenAll(ts)).ContinueWith<Task>(ResponseW);
try
{
await t3;
}
catch (Exception oe)
{
string err = oe.Message + oe.StackTrace;
}
}
private Task ResponseW(Task T)
{
hc.Response.Write(Cache["x"].ToString());
return T;
}
private async Task doSomeThing2(int time = 1000000)
{
int x = 0;
for (int i = 0; i < time; i++)
{
if (Cache["t1tot2"] == null)
{
hc.Response.Write("“atime=" + DateTime.Now.ToString() + "”");
hc.Response.Write("“i=" + i + "”");
try
{
await Task.Delay(TimeSpan.FromSeconds(99999), source.Token);
}
catch(Exception oe) { hc.Response.Write("“xtime=" +oe.Message+oe.StackTrace + "”"); }
hc.Response.Write("“xtime=" + DateTime.Now.ToString() + "”");
}
if (Cache["t1tot2"] != null)
{
hc.Response.Write("“btime=" + DateTime.Now.ToString() + "”");
x = (int)Cache["t1tot2"] + 88;
Cache["x"] = x;
return;
}
}
}
private async Task doSomeThing1()
{
await Task.Delay(2000);
hc.Response.Write("“ctime=" + DateTime.Now.ToString() + "”");
Cache["t1tot2"] = 10;
if (Cache["t2"] != null)
{
Task t2 = Cache["t2"] as Task;
hc.Response.Write("“dtime=" + DateTime.Now.ToString() + "”");
source.Cancel();
hc.Response.Write("“etime=" + DateTime.Now.ToString() + "”");
}
}
被朋友提醒 发现之前其实就已经用CancellationTokenSource解决了 只是我时间控制上有问题 所以造成了异常。。。我没注意 没捕获 所以 错以为CancellationTokenSource造成delay外面的那层task也跳出了
现在发现是时间差问题 特此结贴 谢谢 田兄 哈哈哈