我正在尝试解决我的 UI 被阻止但我不明白为什么的问题。
public Task AddStuff(string myID, List<string> otherIDs)
{
Action doIt = () =>
{
this.theService.AddStuff(myID, otherIDs);
};
return Task.Factory.StartNew(doIt, TaskCreationOptions.LongRunning);
}
如果列表很长,调用可能需要 30 秒,并且整个应用程序变得无响应(在 Windows 7 中变成白色)。
有没有不同的方法来做到这一点,所以它不会阻塞用户界面?
编辑
好的,所以有很多关于此的代码,我将尝试保持相关性。我确实意识到回到原始代码,我已经删除了一些可能很重要的东西。我应该使用不同的 TaskSchedulerTaskScheduler.Current
吗?
此外,没有阻止任何此代码的等待语句,并且服务不与 UI 交互。
Task.Factory.StartNew(objState =>
{
LoadAssets(objState);
}, state, this.cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
private void LoadAssets(object objState)
{
LoadAssetsState laState = (LoadAssetsState)objState;
List<string> assetIDs = new List<string>();
for (int i = 0; i < laState.AddedMediaItems.Count; i++)
{
if (laState.CancellationToken.IsCancellationRequested)
return;
string assetId = this.SelectFilesStep.AssetService.GetAssetId(laState.AddedMediaItems[i], laState.ActiveOrder.OrderID);
assetIDs.Add(assetId);
}
if (laState.CancellationToken.IsCancellationRequested)
return;
this.ApiContext.AddAssetToProduct(laState.ActiveOrder.OrderID, laState.ActiveProduct.LineID, assetIDs, laState.Quantity, laState.CancellationToken).ContinueWith(task =>
{
if (laState.CancellationToken.IsCancellationRequested)
return;
App.ApiContext.GetOrderDetails(laState.ActiveOrder.OrderID, false, laState.CancellationToken).ContinueWith(orderDetailsTask =>
{
if (laState.CancellationToken.IsCancellationRequested)
return;
this.activeOrder = orderDetailsTask.Result;
this.StandardPrintProductsStep.Synchronize(this.activeOrder);
});
});
}
public Task AddAssetToProduct(string orderID, string lineID, List<string> assetIDs, int quantity, CancellationToken? cancellationToken = null)
{
Action doIt = () =>
{
if (cancellationToken.IsCancellationRequested())
return;
this.ordersService.AddAssetToProduct(orderID, lineID, assetIDs, quantity);
};
if (cancellationToken != null)
return Task.Factory.StartNew(doIt, cancellationToken.Value, TaskCreationOptions.LongRunning, TaskScheduler.Current);
else
return Task.Factory.StartNew(doIt, TaskCreationOptions.LongRunning);
}
编辑
我在服务调用之前和之后放置了断点,它是阻塞 UI 的服务调用,而不是任何其他行。
听起来没有理由阻止它,所以我想如果它很长,我会分解列表并进行多次调用。我只是想确保我的任务逻辑没有遗漏任何东西。