我的 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.Wait
和 Task.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 一个 Task
或 Task<T>
,除非它是一个事件处理程序,那么 return 类型必须是 void
.
public async Task GetFolderITemsAsync()
{
var folderItemListResult = await search.GetFolderContent(folder));
// .. use folderItemListResult
}
我最近 blogged 关于这个,你可以在那里找到更多细节。
我一直在用 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.Wait
和 Task.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 一个 Task
或 Task<T>
,除非它是一个事件处理程序,那么 return 类型必须是 void
.
public async Task GetFolderITemsAsync()
{
var folderItemListResult = await search.GetFolderContent(folder));
// .. use folderItemListResult
}
我最近 blogged 关于这个,你可以在那里找到更多细节。