开始没有执行

时间:2013-05-31 09:11:31

标签: c# task

我必须从Azure加载一些对象。我计划将它们加载五到五,以便花费更少的时间(延迟加载):

ProductManager.LoadProduct调用我的ProductAccess.LoadProduct 最后一种方法从azure加载产品,然后引发一个事件,以便管理者可以获得产品。然后,如果它收到产品,它再次调用ProductAccess.LoadProduct。 等....

不能使用await / async,因为它是跨平台代码(monodroid / monotouch稳定版仍然没有等待/异步)。

第一次加载是正确的,然后第二次调用有效,但似乎我的任务没有执行(开始不执行我的第二个任务......)。我检查线程号,第二次,在主线程上执行Task.Factory.StartNew(()=>我尝试通过指定长时间运行来修复它但仍然无效。

这是我的代码:

经理方:

public void LoadProduct() 
{
    ProductAccess.LoadProductsAsync()
}

public void receiveProductsAsync(Object pa, EventArgs e)
{
    if (((ProductEventArgs)e).GetAttribute.Equals("LoadProductsAsync"))
    {
        IoC.Resolve<IProductAccess>().RequestEnded -= receiveProductsAsync;

        if ( ((ProductEventArgs)e).LP).Count() != 0)                       
           LoadProductsAsync();

        Products = Products.Concat(((ProductEventArgs)e).LP).ToList();
        if (((ProductEventArgs)e).E != null)
        {
            if (RequestEnded != null)
                RequestEnded(this, new OperationEventArgs() { Result = false, E = ((ProductEventArgs)e).E, GetAttribute = "LoadProductsAsync" });
        }
        else
        {
            if (RequestEnded != null)
            {
                RequestEnded(this, new OperationEventArgs() { Result = true, GetAttribute = "LoadProductsAsync" });
            }
        }
    }
}

访问方:

public void LoadProductsAsync()
{
    Task<ProductEventArgs>.Factory.StartNew(() =>
    {
        var longRunningTask = new Task<ProductEventArgs>(() =>
        {
            try
            {
                var _items = this.table.Select(x => new Product(.....)).Skip(nbrProductLoaded).Take(nbrProductToLoadAtEachTime).ToListAsync().Result;
                this.nbrProductLoaded += _items.Count();
                Task.Factory.StartNew(() => synchronizeFavorite(_items));
                return new ProductEventArgs() { LP = _items, GetAttribute = "LoadProductsAsync" };
            }
            catch (Exception e)
            {
                return new ProductEventArgs() { E = e, GetAttribute = "LoadProductsAsync" };
            }
        }, TaskCreationOptions.LongRunning);

        longRunningTask.Start();

        if (longRunningTask.Wait(timeout)) 
            return longRunningTask.Result;

        return new ProductEventArgs() { E = new Exception("timed out"), GetAttribute = "LoadProductsAsync" };

    }, TaskCreationOptions.LongRunning).ContinueWith((x) => {
        handleResult(x.Result);
    }, TaskScheduler.FromCurrentSynchronizationContext());
}

1 个答案:

答案 0 :(得分:1)

默认情况下,

Task.Factory.StartNew会使用当前的TaskScheduler

第一次,您没有在任务中运行,因此当前TaskScheduler是默认的TaskScheduler(将在线程池上运行)。

使用handleResultTaskScheduler.FromCurrentSynchronizationContext计划回原始上下文时,将在主线程上的任务中运行handleResult。因此,在该上下文中,当前TaskScheduler是用户界面TaskScheduler,而不是默认的TaskScheduler

要解决此问题,请将TaskScheduler.Default显式传递给您要在线程池线程上运行的任何StartNew(并删除LongRunning)。