我开始创建一些将触发异步操作的类,我希望客户端注册一个回调来接收一些结果。最后我达到了以下代码。这只是一个例子,我想知道是否有更好的方法可以使用TaskFactory
和Action<>, Func<>
以下是客户端基本示例:
Client client2 = new Client();
client2.GetClientList(ClientCallBack);
private static void ClientCallBack(List<Client> listado)
{
//Receive the list result and do some stuff in UI
}
这是Client类GetCLientList
异步示例:
public void GetClientList(Action<List<Client>> Callback)
{
List<Client> listado=null;
Task.Factory.StartNew(() =>
{
listado = new List<Client>{
new Client{ apellidos="Landeras",nombre="Carlos",edad=25},
new Client{ apellidos="Lopez", nombre="Pepe", edad=22},
new Client{ apellidos="Estevez", nombre="Alberto", edad=28}
};
//Thread.Sleep to simulate some load
System.Threading.Thread.Sleep(4000);
}).ContinueWith((prevTask) =>
{
Callback(listado);
}
);
}
有更好的方法吗?我知道我可以从我的函数返回Task
并在客户端注册continueWith
,但我想将它包装在类中。
修改
我发布了另一个例子。我试图制作sync
的{{1}} / async
个版本。
这种方法是否正确?:
webrequest
答案 0 :(得分:5)
首先,你的方法似乎并不是异步的,所以你不会从使它看起来像一个人那里获得太多收益。如果您的方法的用户决定在另一个线程上运行它,他们可以自己完成。
其次,如果您可以使用C#5.0,则应遵循the Task-based asynchronous pattern,以使您的方法更易于使用。有了这个(假设你有理由忽略我上面的第一点),你的代码可能如下所示:
public Task<List<Client>> GetClientListAsync()
{
return Task.Run(() =>
{
var list = new List<Client>
{
new Client { apellidos="Landeras", nombre="Carlos", edad=25 },
new Client { apellidos="Lopez", nombre="Pepe", edad=22 },
new Client { apellidos="Estevez", nombre="Alberto", edad=28 }
};
//Thread.Sleep to simulate some load
System.Threading.Thread.Sleep(4000);
return list;
});
}
或者,如果您想让您的代码实际上异步:
public async Task<List<Client>> GetClientListAsync()
{
var list = new List<Client>
{
new Client { apellidos="Landeras", nombre="Carlos", edad=25 },
new Client { apellidos="Lopez", nombre="Pepe", edad=22 },
new Client { apellidos="Estevez", nombre="Alberto", edad=28 }
};
//Task.Delay() to simulate some load
await Task.Delay(4000);
return list;
}
在这两种情况下,您都可以使用此方法而不使用async
方法中的回调,如下所示:
var client = new Client();
var list = await client.GetClientListAsync();
//Receive the list result and do some stuff in UI
第三,如果您不想(或不能)使用async
- await
,那么您的代码很接近,但非常正确。问题是回调实际上不会在UI线程上执行。为此,您需要使用TaskScheduler.FromCurrentSynchronizationContext()
。
此外,Client
采用GetClientList()
方法的设计对我来说似乎很可疑。这种方法可能属于某种存储库对象,而不属于Client
。
答案 1 :(得分:-2)
但是如果你使用await client.GetClientAsync .... theard将被阻止。
添加回调的任何新方法?或者我应该使用4.0 TPL?
我没有看到等待的价值。它阻止了当前线程,丢失了其他任务。