我爲Silverlight 4(Mono的一個端口)使用Nuget包System.Threading.Tasks。我不斷收到InvalidOperationException
(「基礎任務已經在三個最終狀態之一:RanToCompletion,斷陷,或取消」)以下:TaskCompletionSource <DeploymentCatalog>有什麼問題?
var tasks = new Task<DeploymentCatalog>[2];
//Catalog the XAP downloaded by the Application Loader, the BiggestBox Index:
var uri0 = new Uri(Application.Current.
Host.InitParams["LoaderInfoXapPath"], UriKind.Relative);
tasks[0] = CompositionUtility.DownloadCatalogAsync(uri0);
//Catalog the XAP with the BiggestBox Index Part:
var uri1 = new Uri(Application.Current
.Host.InitParams["BiggestBoxIndexXapPath"], UriKind.Relative);
tasks[1] = CompositionUtility.DownloadCatalogAsync(uri1);
//tasks did not run by default...
//tasks[0].Start();
//tasks[1].Start();
Task.WaitAll(tasks);
this.AddToAggregateCatalog(tasks[0].Result);
this.AddToAggregateCatalog(tasks[1].Result);
base.Compose();
其中DownloadCatalogAsync
是:
/// <summary>
/// Downloads the catalog
/// in a <see cref="System.Threading.Task"/>.
/// </summary>
/// <param name="location">The location.</param>
/// <param name="downloadCompleteAction">The download complete action.</param>
[SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope",
Justification = "Reliable disposal depends on callers.")]
public static Task<DeploymentCatalog> DownloadCatalogAsync(Uri location)
{
return DownloadCatalogAsTask(location, null);
}
/// <summary>
/// Downloads the catalog
/// in a <see cref="System.Threading.Task"/>.
/// </summary>
/// <param name="location">The location.</param>
/// <param name="downloadCompleteAction">The download complete action.</param>
/// <remarks>
/// For details, see the 「Converting an Event-Based Pattern」 section in
/// 「Simplify Asynchronous Programming with Tasks」
/// by Igor Ostrovsky
/// [http://msdn.microsoft.com/en-us/magazine/ff959203.aspx]
/// </remarks>
[SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope",
Justification = "Reliable disposal depends on callers.")]
public static Task<DeploymentCatalog> DownloadCatalogAsync(Uri location,
Action<object, AsyncCompletedEventArgs> downloadCompleteAction)
{
var completionSource = new TaskCompletionSource<DeploymentCatalog>();
var catalog = new DeploymentCatalog(location);
catalog.DownloadCompleted += (s, args) =>
{
if(args.Error != null) completionSource.SetException(args.Error);
else if(args.Cancelled) completionSource.SetCanceled();
else
{
completionSource.SetResult(s as DeploymentCatalog); //exception thrown here
if(downloadCompleteAction != null)
downloadCompleteAction.Invoke(s, args);
}
};
catalog.DownloadAsync();
return completionSource.Task;
}
我使用這種模式與WebClient
和它工作正常(但我沒有Start()
明確的任務---但我沒有測試WebClient
與單端口版本的任務並行庫(用於Silverlight)。我應該這樣做...
我會把這些新的4.5公約放在心上。我沒有提到我使用帶有TPL Mono端口的Silverlight 4。不幸的是,我不得不明確地調用'Start()',否則任務會返回'WaitingForActivation' - 這種意外的行爲可能與這個Mono的東西有關? – rasx 2012-03-02 17:58:03
@rasx可以的,你必須調用Start,只要確保在返回Task的方法內啓動它,而不是將它留給消費者來啓動它。就行爲而言,是的,這是因爲您必須採用Silverlight + Mono TPL庫的方法。在.NET 4 TPL中,你更可能使用Task.Factory.StartNew。 – 2012-03-05 19:44:26