Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 下载不影响用户界面的文件_C#_Windows 8_Download_Windows 8.1_Dotnet Httpclient - Fatal编程技术网

C# 下载不影响用户界面的文件

C# 下载不影响用户界面的文件,c#,windows-8,download,windows-8.1,dotnet-httpclient,C#,Windows 8,Download,Windows 8.1,Dotnet Httpclient,我们目前正在使用HttpClient下载文件,因为我们的后端需要证书 我有一个控件-FileRow,它是一个UI元素,有一些code-behind文件下载方法,如下所示: if (FileIsDownloaded == false) { await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () =>

我们目前正在使用
HttpClient
下载文件,因为我们的后端需要证书

我有一个控件-
FileRow
,它是一个UI元素,有一些
code-behind
文件下载方法,如下所示:

    if (FileIsDownloaded == false)
    {
        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () =>
        {
            DataManager.Instance.DownloadFile(this);
        });
    }
    if (ThumbnailIsDownloaded == false)
    {
        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () =>
        {
            DataManager.Instance.DownloadThumbnail(this);
        });
    }
下载单个项目是可以的,但当我单击“下载全部”(大约50个项目)时,整个UI开始冻结

正如您所看到的,我曾尝试将请求的优先级设置为较低,但结果仍然相同

对常见问题的答复:

1) 是的,这些文件应该可以一次全部下载,而不是一个接一个地下载。
2)
DataManager.Instance.DownloadThumbnail(this)
-我这样做是为了对当前控件进行引用,以便在进度条中报告进度

有什么建议吗

编辑:

下载过程如下所示:

public async void DownloadFile(FileRow fileRow)
{
    //Lot of checking for if file exist, if version is the same
    string LocalFilename = await DownloadManager.DownloadFile(fileRow.MyFile.file.id, fileRow.MyFile.file.version, fileRow.MyFile.file.filename,fileRow);
    // next is just using the filename string
}
最后是我的下载:

public static async Task<string> DownloadFileOfCustomerAssetRow(int? id, int? version, string filename, FileRow fileRow)
    {
        try
        {
            HttpClientHandler aHandler = new HttpClientHandler();
            aHandler.ClientCertificateOptions = ClientCertificateOption.Automatic;
            HttpClient aClient = new HttpClient(aHandler);
            customerAssetRow.CurrentFileDownload = aClient;
            aClient.DefaultRequestHeaders.ExpectContinue = false;
            HttpResponseMessage response = await aClient.GetAsync(WebServices.BackendStartUrl + "getFileData?id=" + id + "&version=" + version, HttpCompletionOption.ResponseHeadersRead);
            var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, Windows.Storage.CreationCollisionOption.GenerateUniqueName);
            fileRow.FileName = file.Name;
            using (var fs = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
            {
                Stream stream = await response.Content.ReadAsStreamAsync();
                IInputStream inputStream = stream.AsInputStream();
                ulong totalBytesRead = 0;
                while (true)
                {
                    IBuffer buffer = new Windows.Storage.Streams.Buffer(1024);
                    buffer = await inputStream.ReadAsync(
                        buffer,
                        buffer.Capacity,
                        InputStreamOptions.None);
                    if (buffer.Length == 0)
                    {
                        break;
                    }
                    totalBytesRead += buffer.Length;
                    fileRow.Progress.Value = fileRow.Progress.Value + 1024;
                    await fs.WriteAsync(buffer);
                }
                inputStream.Dispose();
            }
            fileRow.Progress.Visibility = Visibility.Collapsed;
            return file.Name;
        }
        catch (Exception e)
        {
            ErrorReporter.ReportError("Error in DownloadManager.cs in function DownloadFile.", e);
            return "";
        }
    }
customerassetrow的公共静态异步任务下载文件(int?id,int?version,字符串文件名,FileRow)
{
尝试
{
HttpClientHandler aHandler=新的HttpClientHandler();
aHandler.ClientCertificateOptions=ClientCertificateOptions.Automatic;
HttpClient aClient=新的HttpClient(aHandler);
CustomErasetRow.CurrentFileDownload=aClient;
aClient.DefaultRequestHeaders.ExpectContinue=false;
HttpResponseMessage response=等待aClient.GetAsync(WebServices.BackendStartUrl+“getFileData?id=“+id+”&version=“+version,HttpCompletionOption.ResponseHeadersRead);
var file=wait ApplicationData.Current.LocalFolder.CreateFileAsync(文件名,Windows.Storage.CreationCollisionOption.GenerateUniqueName);
fileRow.FileName=file.Name;
使用(var fs=await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
{
Stream=wait response.Content.ReadAsStreamAsync();
IIInputStream inputStream=stream.asiInputStream();
ulong totalBytesRead=0;
while(true)
{
IBuffer buffer=新的Windows.Storage.Streams.buffer(1024);
缓冲区=等待inputStream.ReadAsync(
缓冲器
缓冲区,容量,
InputStreamOptions(无);
如果(buffer.Length==0)
{
打破
}
totalBytesRead+=缓冲区长度;
fileRow.Progress.Value=fileRow.Progress.Value+1024;
等待fs.WriteAsync(缓冲区);
}
inputStream.Dispose();
}
fileRow.Progress.Visibility=可见性。已折叠;
返回文件名;
}
捕获(例外e)
{
ErrorReporter.ReportError(“函数DownloadFile.中的DownloadManager.cs中的错误”,e);
返回“”;
}
}

您的
异步
方法延续可能过度中断了UI线程。通过引入
IProgress
报告程序,尝试在您的后台逻辑(
DownloadFileOfCustomerAssetRow
)和您的UI(
FileRow
)之间建立更紧密的分离。然后确保后台逻辑中的每个
await
上都有
ConfigureAwait(false)

public static async Task<string> DownloadFileOfCustomerAssetRow(int? id, int? version, string filename, IProgress<int> progress)
{
    HttpClientHandler aHandler = new HttpClientHandler();
    aHandler.ClientCertificateOptions = ClientCertificateOption.Automatic;
    HttpClient aClient = new HttpClient(aHandler);
    customerAssetRow.CurrentFileDownload = aClient;
    aClient.DefaultRequestHeaders.ExpectContinue = false;
    HttpResponseMessage response = await aClient.GetAsync(WebServices.BackendStartUrl + "getFileData?id=" + id + "&version=" + version, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
    var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, Windows.Storage.CreationCollisionOption.GenerateUniqueName).ConfigureAwait(false);
    fileRow.FileName = file.Name;
    using (var fs = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite).ConfigureAwait(false))
    {
        Stream stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
        IInputStream inputStream = stream.AsInputStream();
        ulong totalBytesRead = 0;
        while (true)
        {
            IBuffer buffer = new Windows.Storage.Streams.Buffer(1024);
            buffer = await inputStream.ReadAsync(
                buffer,
                buffer.Capacity,
                InputStreamOptions.None).ConfigureAwait(false);
            if (buffer.Length == 0)
            {
                break;
            }
            totalBytesRead += buffer.Length;
            if (progress != null)
                progress.Report(totalBytesRead);
            await fs.WriteAsync(buffer).ConfigureAwait(false);
        }
        inputStream.Dispose();
    }
    return file.Name;
}
customerassetrow的公共静态异步任务下载文件(int?id,int?version,字符串文件名,IProgress progress)
{
HttpClientHandler aHandler=新的HttpClientHandler();
aHandler.ClientCertificateOptions=ClientCertificateOptions.Automatic;
HttpClient aClient=新的HttpClient(aHandler);
CustomErasetRow.CurrentFileDownload=aClient;
aClient.DefaultRequestHeaders.ExpectContinue=false;
HttpResponseMessage response=await aClient.GetAsync(WebServices.BackendStartUrl+“getFileData?id=“+id+”&version=“+version,HttpCompletionOption.ResponseHeaderRead”).ConfigureAwait(false);
var file=await ApplicationData.Current.LocalFolder.CreateFileAsync(文件名,Windows.Storage.CreationCollisionOption.GenerateUniqueName).ConfigureAwait(false);
fileRow.FileName=file.Name;
使用(var fs=await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite).ConfigureAwait(false))
{
Stream=await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
IIInputStream inputStream=stream.asiInputStream();
ulong totalBytesRead=0;
while(true)
{
IBuffer buffer=新的Windows.Storage.Streams.buffer(1024);
缓冲区=等待inputStream.ReadAsync(
缓冲器
缓冲区,容量,
InputStreamOptions.None)。配置等待(false);
如果(buffer.Length==0)
{
打破
}
totalBytesRead+=缓冲区长度;
如果(进度!=null)
进度报告(totalBytesRead);
wait fs.WriteAsync(缓冲区).configureWait(false);
}
inputStream.Dispose();
}
返回文件名;
}

HttpClient涉及到哪里?请参阅我的问题编辑作为旁注,每次处理HttpClient时,它都会关闭TCP连接,下一个HttpClient必须重新打开连接并重新协商HTTPS连接。对所有下载重新使用同一个HttpClient实例会更有效率。没有用,只是在从您正在使用的其他线程进行封送处理时出现错误而失败,
Progress
,对吗?没有编写自己的
IProgress
?Progress不是只能在后台下载程序中使用吗?没有<代码>进度设计用于
异步
方法。