首页 新闻 搜索 专区 学院

怎么从外部取消一个await Task.Delay操作?

0
悬赏园豆:50 [已关闭问题] 关闭于 2015-12-11 17:15

怎么从外部取消一个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自己不停的重新检查交换变量,这样太没效率了,谁知道具体怎么办?另外整个过程都要是异步的  否则就没有意义了

雷兽的主页 雷兽 | 初学一级 | 园豆:162
提问于:2015-12-11 13:55
< >
分享
所有回答(2)
0
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("任务一完成了");
        }
    }
}
田麦成 | 园豆:2004 (老鸟四级) | 2015-12-11 15:04

田兄的这ManualResetEvent WaitOne还是同步等待  跟delay没法比

 

如果要整这个 我自己也有不少办法

 

flag.WaitOne(3000)的时候   Task。Run的这个线程在运行

 

我要求该线程也被delay那样的挂起

 

否则同步等待毫无意义

支持(0) 反对(0) 雷兽 | 园豆:162 (初学一级) | 2015-12-11 16:38

我的场景中 请求行为希望相关线程都被挂起 释放回线程池 而不是另外开一个线程去等待

支持(0) 反对(0) 雷兽 | 园豆:162 (初学一级) | 2015-12-11 16:40

如果那么简单 我就不会贴了 。。我也是10来年的开发了

支持(0) 反对(0) 雷兽 | 园豆:162 (初学一级) | 2015-12-11 16:40
1

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也跳出了

现在发现是时间差问题  特此结贴  谢谢 田兄 哈哈哈

雷兽 | 园豆:162 (初学一级) | 2015-12-11 17:13
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册