我的 TaskCompletetion 性能代码

My TaskCompletetion code for performance

我一直在用 Xamarin.iOS 开发一个 ios 应用程序。我们有一个 WCF 服务,我使用由 silverlight 工具 slsvcutil 创建的动态代理,所以现在所有服务方法都是异步的。

我调用了这些方法,但我不确定我是否以最佳方式进行了调用。因为这对我来说似乎有点奇怪。我是第一次使用 taskcompletetion class。我发现了一些与我的代码相似的示例。

这里只是我如何调用函数并获得结果的代码

var folderItemListResult = Task.Run(() => search.GetFolderContent(folder));
folderItemListResult.Wait();
folderItemList = folderItemListResult.Result;

这是获取文件夹内容的方法

public Task<List<FolderItem>> GetFolderContent(FolderProfile folder)
{
    var tcs = new TaskCompletionSource<List<FolderItem>>();

    service.GetFolderItemsCompleted += (sender, args) =>
    {
        try
        {

            if (args.Result != null)
                tcs.TrySetResult(args.Result.ToList());
            else
                tcs.SetResult(new List<FolderItem>());
        }
        catch
        {
            tcs.SetResult(new List<FolderItem>()); 
        }


    };

    try
    {
        service.GetFolderItemsAsync(_library, folder);
    }
    catch { }

    return tcs.Task;
} 

这个方法的实现对我来说看起来不错,虽然我会在 catch 块中设置任务完成源的例外,但如果你喜欢忽略它,那取决于你。

如果您使用的是 .NET 4.5,您调用函数的代码可以简化为

var folderItemListResult = await search.GetFolderContent(folder));

您在进行 Task.WaitTask.Result 等阻塞调用时需要小心。这些阻塞当前线程并可能导致 deadlock

如果您使用的是 .NET 4.0,您的调用代码可以简化为:

search.GetFolderContent(folder)).ContinueWith(t =>
{         
     // t is the completed task, you may need to check t.Exception
     // to see if it there was an error.

     var folderItemListResult = t.Result;
     // use the result...
});

因为 await 对你可用,所以使用它是最容易的。您使用它的方法必须标记为 async 以允许使用 await 并且它应该 return 一个 TaskTask<T>,除非它是一个事件处理程序,那么 return 类型必须是 void.

public async Task GetFolderITemsAsync()
{
    var folderItemListResult = await search.GetFolderContent(folder));

    // .. use folderItemListResult
}

我最近 blogged 关于这个,你可以在那里找到更多细节。