我有一個WCF服務公開兩個端點(一個TCP和另一個REST)。我在WCF中有一個返回文件流的方法。 在我的客戶端應用程序中,我使用異步調用來開始下載文件並將其保存爲本地文件。完成線程後,我需要返回到主線程,以便我可以更新UI。爲此,我使用Dispatcher.Invoke。WCF文件在單獨線程上的流式下載掛起,同時返回到主線程
問題是,其餘端點似乎下載並保存文件,但TCP端點會引發超時錯誤。我的另一個問題是,在代碼完成並返回到Dispatcher.Invoke行的兩個端點中,它只是掛起而不能繼續。
我調試了它,服務調用正如預期的那樣在工作線程上工作,但當我嘗試使用Dispatcher.Invoke返回到主線程(UI)時,整個應用程序以某種方式掛起。我也嘗試過Dispatcher.BeginInvoke,但結果相同。
當我調用任何其他WCF方法(它返回JSON或數據約定)時,相同的應用程序和代碼工作正常。在這種情況下,我可以使用Dispatcher.Invoke回到主線程。但是有些時候,我正在調用WCF方法來下載它剛剛掛起的文件。
我試圖列出下面的代碼。不知道我在這裏做錯了什麼。我的webConfig設置爲最大尺寸。我不期待大文件(通常在2-5 MB之間)。
你能讓我知道我在做什麼錯嗎?我期望下載和寫入文件完成,然後移動到主線程。我希望它是流媒體,以便即使將來文件大小增加,我也可以處理。
任何指針/建議將有所幫助。
- 吉里賈·
public static class Holder
{
public static Dispatcher CurrentDispatcher { get; set; } // Set when application loads
}
public class Downloader
{
public Downloader()
{
}
public void DownloadFileAndAct(string fileName)
{
AsyncCallback callback = new AsyncCallback(this.DownloadComplete);
Func<string, string> del = new Func<string, string>(this.DownloadStream);
del.BeginInvoke(fileName, callback, this);
}
private void DownloadComplete(IAsyncResult ar)
{
AsyncResult res = (AsyncResult)ar;
Func<string, string> objCaller = (Func<string, string>)res.AsyncDelegate;
var filePath = objCaller.EndInvoke(ar);
// The below code is where it just hangs
Holder.CurrentDispatcher.Invoke(new Action(() =>
{
// Do some stuff on main thread like display the file in a selction list
}));
}
private string DownloadStream(string fileName)
{
TestServiceClient client = new TestServiceClient();
//1st approach
var stream = client.DownloadFile(fileName);
client.Close();
var savePath = @"D:\MySavedLocation\" + fileName;
using (var file = File.Create(savePath))
{
stream.CopyTo(file);
}
// 2nd approach (tried this too)
//const int bufferSize = 2048;
//byte[] buffer = new byte[bufferSize];
//using (FileStream outputStream = new FileStream(savePath,
// FileMode.Create, FileAccess.Write))
//{
// int bytesRead = client.DownloadFile(fileName).Read(buffer, 0, bufferSize);
// while (bytesRead > 0)
// {
// outputStream.Write(buffer, 0, bytesRead);
// bytesRead = client.DownloadFile(fileName).Read(buffer, 0, bufferSize);
// }
// outputStream.Close();
//}
//client.Close();
return savePath;
}
}
Henk,如果我不清楚,我很抱歉,但這兩種方法都對我造成問題。我的代碼在調度程序行返回時掛起(在我的代碼示例中標記爲「//下面的代碼就是它掛起的位置」)。 - Giirja – Shankar
對不起,關於初始代碼中的clinet.Close()。我的代碼正是你所說的。在CopyTo(..)後關閉客戶端。我的不好是一個錯字。 - Girija – Shankar