【发布时间】:2014-07-29 21:25:16
【问题描述】:
我正在测试我的类库,它将异步发布到网络服务器。 由于要发送的数据需要不同的操作,我插入方法来处理并将它们发送到阻塞集合中。一个永远运行的任务从集合中提取每个方法并执行它。 问题是如果发布失败,错误不会冒泡到 wpf 调用者模块。
这是库模块
private Task queueInvio;
private BlockingCollection<Action> codaInvio = null;
public MotoreClient()
{
codaInvio = new BlockingCollection<Action>();
queueInvio = Task.Factory.StartNew(() =>
{
while (true)
{
Action azione = null;
if (codaInvio.TryTake(out azione))
{
try
{
azione();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
}
, CancellationToken.None
, TaskCreationOptions.LongRunning
, TaskScheduler.Default);
}
这是wpf测试程序调用的方法
public void InviaAggiornamento(TipoAggiornamento tipoAggiornamento)
{
string nomePaginaApi = String.Empty;
HttpContent contenuto = null;
switch (tipoAggiornamento)
{
// blah blah code
}
// exception capture here, but not rethrown to the wpf module
codaInvio.Add(async () =>
{
try
{
await InviaAggiornamento(nomePaginaApi, contenuto);
}
catch (Exception ex)
{
throw;
}
});
}
这是制作异步帖子的方法
private async Task InviaAggiornamento(string nomePaginaApi, HttpContent contenuto)
{
HttpClient httpClient = new HttpClient();
string riposta = String.Empty;
if (!string.IsNullOrEmpty(indirizzoServer))
{
try
{
httpClient.BaseAddress = new Uri(IndirizzoServer);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", USERNAME, PASSWORD))));
var response = await httpClient.PostAsync("api/liveTimingApi/" + nomePaginaApi, contenuto);
if (response.StatusCode != HttpStatusCode.NoContent)
throw new Exception("Richiesta PostAsync fallita.");
if (!response.IsSuccessStatusCode)
{
string rispostaErrore = string.Empty;
if (!string.IsNullOrEmpty(response.ReasonPhrase))
rispostaErrore += " ReasonPhrase: " + response.ReasonPhrase;
if (!string.IsNullOrEmpty(response.Content.ReadAsStringAsync().Result))
rispostaErrore += " Result: " + response.Content.ReadAsStringAsync().Result;
throw new ServerException(rispostaErrore.Trim());
}
}
catch (HttpRequestException hre)
{
throw new Exception("HttpRequestException: " + hre.Message);
}
catch (TaskCanceledException)
{
throw new Exception("Richiesta cancellata (TaskCanceledException).");
}
catch (Exception ex)
{
throw new Exception("Exception: " + ex.Message);
}
finally
{
if (httpClient != null)
{
httpClient.Dispose();
httpClient = null;
}
}
}
}
这是模拟数据发送的 wpf 模块
private void btnSendTest_Click(object sender, RoutedEventArgs e)
{
motoreClient.IndirizzoServer = "http://localhost:721";
motoreClient.AggiungiRigaProgrammaOrario(1, 1, "GaraDescrizione", DateTime.Now, "XXX", "SessioneDescrizione", "1:00:00", true);
try
{
motoreClient.InviaAggiornamento(TipoAggiornamento.ProgrammaOrario);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
由于 IndirizzoServer(服务器地址)是假的,我有一个 HttpRequest 异常。 我在 codaInvio.Add try/catch 块中捕获它,但我无法将它重新抛出到调用方 wpf 模块。 Visual Studio 说异常不是由调用者代码处理的。 为什么?我正在使用 try/catch 所有相关的代码。
如果我不清楚,请告诉我。
马可
【问题讨论】:
-
如果您可以将这些 sn-ps 重构为一个简短但完整的程序,我们可以轻松复制、粘贴、编译和运行,这将非常有帮助...
-
给你。带有解决方案的拉链……只需按下按钮。我正在等待一个消息框出现,而是在 codaInvio.Add() uploadmb.com/dw.php?id=1406633237
-
不,我没有要求 zip 文件。这实际上是 WPF 特定的吗?您是否在控制台应用程序中尝试过?您可能可以在一个足够短的程序中重现它,只需直接粘贴...
标签: c# asynchronous task-parallel-library task async-await