C# 启动未执行
我必须从Azure加载一些对象。为了节省时间,我计划五个五个地加载它们(有点懒加载): ProductManager.LoadProduct调用我的ProductAccess.LoadProduct 最后一个方法从azure加载产品,然后引发一个事件,以便经理可以获取该产品。然后,如果它收到产品,它将再次调用ProductAccess.LoadProduct。 等等 无法使用await/async,因为它是跨平台代码(monodroid/monotouch稳定版仍然没有await/async) 第一次加载是正确的,然后第二次调用工作,但我的任务似乎没有执行(开始不执行我的第二个任务…)。我检查线程号,第二次,Task.Factory.StartNew(()=>在主线程上执行。我试图通过指定长时间运行来修复它,但仍然不起作用 这是我的密码: 经理方:C# 启动未执行,c#,task,C#,Task,我必须从Azure加载一些对象。为了节省时间,我计划五个五个地加载它们(有点懒加载): ProductManager.LoadProduct调用我的ProductAccess.LoadProduct 最后一个方法从azure加载产品,然后引发一个事件,以便经理可以获取该产品。然后,如果它收到产品,它将再次调用ProductAccess.LoadProduct。 等等 无法使用await/async,因为它是跨平台代码(monodroid/monotouch稳定版仍然没有await/async)
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 LoadProduct()
{
ProductAccess.LoadProductsAsync()
}
public void receiveProductsAsync(对象pa、事件参数e)
{
if(((ProductEventArgs)e).GetAttribute.Equals(“LoadProductsAsSync”))
{
IoC.Resolve().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(这是一个新操作eventargs(){Result=false,E=((ProductEventArgs)E).E,GetAttribute=“LoadProductsAsync”});
}
其他的
{
if(RequestEnded!=null)
{
RequestEnded(这是一个新的操作eventargs(){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());
}
public void LoadProductsAsync()
{
Task.Factory.StartNew(()=>
{
var longRunningTask=新任务(()=>
{
尝试
{
var\u items=this.table.Select(x=>new Product(…).Skip(nbrProductLoaded).Take(NBRproductToLoadeAchTime.ToListSync().Result;
this.nbrProductLoaded+=\u items.Count();
Task.Factory.StartNew(()=>synchronizeFavorite(_items));
返回新的ProductEventArgs(){LP=\u items,GetAttribute=“LoadProductsAsync”};
}
捕获(例外e)
{
返回新的ProductEventArgs(){E=E,GetAttribute=“LoadProductsAsync”};
}
},TaskCreationOptions.LongRunning);
longRunningTask.Start();
if(longRunningTask.Wait(超时))
返回longRunningTask.Result;
返回新的ProductEventArgs(){E=new Exception(“超时”),GetAttribute=“LoadProductsAsync”};
},TaskCreationOptions.LongRunning)。继续((x)=>{
handleResult(x.Result);
},TaskScheduler.FromCurrentSynchronizationContext());
}
Task.Factory.StartNew
默认情况下将使用当前的TaskScheduler
第一次,您没有在任务内运行,因此当前的TaskScheduler
是默认的TaskScheduler
(将在线程池上运行)
当您使用TaskScheduler.FromCurrentSynchronizationContext
将handleResult
调度回原始上下文时,它将在主线程上的任务内运行handleResult
。因此,在该上下文中,当前的TaskScheduler
是UITaskScheduler
,而不是默认的TaskScheduler
要解决此问题,请显式将
TaskScheduler.Default
传递给要在线程池线程上运行的任何StartNew
(并删除longlunning
)。Task.Factory.StartNew
默认情况下将使用当前的TaskScheduler
第一次,您没有在任务内运行,因此当前的TaskScheduler
是默认的TaskScheduler
(将在线程池上运行)
当您使用TaskScheduler.FromCurrentSynchronizationContext
将handleResult
调度回原始上下文时,它将在主线程上的任务内运行handleResult
。因此,在该上下文中,当前的TaskScheduler
是UITaskScheduler
,而不是默认的TaskScheduler
要解决此问题,请显式地将
TaskScheduler.Default
传递给要在线程池线程上运行的任何StartNew
(并删除longlunning
)。感谢它的工作,也感谢您提供的非常清晰的解释!谢谢你的作品,谢谢你的解释!