Car*_*ras 1 c# asynchronous taskfactory
我开始创建一些将触发异步操作的类,我希望客户端注册一个回调来接收一些结果.最后我达到了以下代码.这只是一个例子,我想知道是否有更好的方法来使用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
}
Run Code Online (Sandbox Code Playgroud)
这是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);
}
);
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法呢?我知道我可以Task从我的函数返回并continueWith在客户端注册,但我想将它包装在类中.
编辑
我发布了另一个例子.我试图制作sync/ async版本的webrequest.这种方法是否正确?:
public string ExecuteRequest(string url)
{
HttpWebRequest httpwebrequest = (HttpWebRequest) WebRequest.Create(url);
HttpWebResponse httpwebresponse = (HttpWebResponse) httpwebrequest.GetResponse();
using (StreamReader sr = new StreamReader(httpwebresponse.GetResponseStream()))
{
return sr.ReadToEnd();
}
}
public void ExecuteRequestAsync(string uri,Action<string> callbackResult)
{
Task.Factory.StartNew(() => ExecuteRequest(uri), CancellationToken.None)
.ContinueWith((task) => callbackResult(task.Result));
}
Run Code Online (Sandbox Code Playgroud)
首先,你的方法似乎并不是异步的,所以你不会因为它看起来像一个人而获得太多收益.如果您的方法的用户决定在另一个线程上运行它,他们可以自己完成.
其次,如果您可以使用C#5.0,则应遵循基于任务的异步模式,以使您的方法更易于使用.有了这个(假设你有理由忽略我上面的第一点),你的代码可能如下所示:
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;
});
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您想使您的代码实际上异步:
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;
}
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,您都可以使用此方法,而无需使用以下方法的回调async:
var client = new Client();
var list = await client.GetClientListAsync();
//Receive the list result and do some stuff in UI
Run Code Online (Sandbox Code Playgroud)
第三,如果你不想(或不能)使用async- await,那么你的代码很接近,但是非常正确.问题是回调实际上不会在UI线程上执行.为此,您需要使用TaskScheduler.FromCurrentSynchronizationContext().
另外,你的设计哪里Client有GetClientList()方法似乎对我很怀疑.这种方法可能属于某种存储库对象,而不是Client.