Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++/CLI

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.91
Vitall
750 / 530 / 23
Регистрация: 03.07.2011
Сообщений: 1,020
#1

DownloadDataAsync(System::Url^) - C++/CLI

13.08.2011, 05:04. Просмотров 1380. Ответов 8
Метки нет (Все метки)

Добрый день ,возникла проблемка с методом DownloadDataAsync(System::Url^) .Ни как дать этому методу
нужный ему System::Url^ .
Делаю так:
C++
1
2
3
4
5
6
7
bool FileFromServer(String^url)
{  Uri^ siteUri = gcnew Uri(url);
    WebClient^ request = gcnew WebClient;
    array<Byte>^newFileData = request->DownloadDataAsync(url);
    File::WriteAllBytes("icon_1.gif",newFileData);
    return true;
}
На что выдает ошибку :Ошибка 1 error C2664: void System::Net::WebClient:: DownloadDataAsync(System::Uri ^): невозможно преобразовать параметр 1 из "System::String ^" в "System::Uri ^" .Как исправить эту ошибку ?
При том что DownloadData(url) работает исправно и не капризничает .Хотел бы использовать метод DownloadDataAsync ,так как он не блокирует работу программы .Но на данный момент этот метод блокирует разработку всей программы так уже пару часов не могу устранить эту ошибку .
Подскажи кто знает
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.08.2011, 05:04
Я подобрал для вас темы с готовыми решениями и ответами на вопрос DownloadDataAsync(System::Url^) (C++/CLI):

Подключение и работа с System, System.IO, System.Collections.Generic; - C++/CLI
Здравствуйте, не подскажите почему не работают using namespace System, using namespace System.Collections.Generic и др. Что нужно сделать...

Как преобразовать System::String в System::String^ - C++/CLI
Как преобразовать System::String в System::String^? Явный пример: return (String(temp)); temp - массив wchar_t, пишет ошибку:

Ошибка An unhandled exception of type 'System.Data.OleDb.OleDbException' occurred in system.data.dll - .NET
добовляю данные в таблицу .mdb (язык C#) string strSql='INSERT INTO tt (ID,F1,F2) VALUES(?,?,?)'; OleDbConnection cn = new...

URL в DataGrid - .NET
Как в DataGrid-е динамически задавать URL? Спасибо!

Классы для сохранения файлов по URL. - .NET
Нужно взять файл по URL (GET''ом) изменить и положить на место (PUT''ом). Какие классы для этого нужно использовать. Формат файла -...

System::String - C++/CLI
Ребят, имеется строка System::String^:&quot;C:\\User\Troliha\Po\gavr.txt&quot; Надо из этой строки получить только &quot;gavr.txt&quot;. Проще говоря...

8
Ma3a
Эксперт С++
619 / 463 / 31
Регистрация: 28.01.2011
Сообщений: 605
13.08.2011, 09:45 #2
Всё правильно, у DownloadData есть перегрузка, принимающая параметр типа String, а у DownloadDataAsync её нет. Да и вообще, вы из строки url создаёте объект типа System::Uri, а никак его не используете
Цитата Сообщение от Vitall Посмотреть сообщение
Uri^ siteUri = gcnew Uri(url);
Передавайте его в метод DownloadDataAsync тогда и должно заработать.
0
Vitall
750 / 530 / 23
Регистрация: 03.07.2011
Сообщений: 1,020
13.08.2011, 16:27  [ТС] #3
Верно ,siteUri не использовал ,спасибо что заметили ,исправил ! Но теперь теперь другую выдает
C++
1
2
3
4
5
6
7
8
9
  bool FileFromServer(String^url)
{
    
    Uri^ siteUri = gcnew Uri(url);
    WebClient^ request = gcnew WebClient;
    array<Byte>^newFileData = request->DownloadDataAsync(siteUri);
    File::WriteAllBytes("icon_1.gif",newFileData);
    return true;
}
Ошибка 1 error C2440: инициализация: невозможно преобразовать "void" в "cli::array<Type> ^"

и так пробовал
C++
1
request->DownloadDataAsync( gcnew Uri(url));
тоже самое
0
Ma3a
Эксперт С++
619 / 463 / 31
Регистрация: 28.01.2011
Сообщений: 605
13.08.2011, 17:16 #4
Vitall, так ну правильно, это же асинхронный вариант операции, функция возвращает void, а для того, чтобы получать данные, надо писать обработчики на соответствующие события, которые будет посылать WebClient, такие как например DownloadDataCompleted, означающее окончание приёма данных. В самом обработчике события полученный массив байтов можно вытащить через DownloadDataCompletedEventArgs->Result. Небольшой пример на эту тему, выводящий количество полученных байтов:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void download_completed(System::Object ^ sender, System::Net::DownloadDataCompletedEventArgs ^ e)
    {
    cli::array<System::Byte> ^ res = e->Result;
    System::Console::WriteLine(res->Length);
    }
 
int main()
    {
    System::Net::WebClient ^ client = gcnew System::Net::WebClient();
    client->DownloadDataCompleted += gcnew System::Net::DownloadDataCompletedEventHandler(&download_completed);
    client->DownloadDataAsync(gcnew System::Uri("http://google.com"));
    System::Console::ReadLine();
    }
1
Vitall
750 / 530 / 23
Регистрация: 03.07.2011
Сообщений: 1,020
13.08.2011, 17:59  [ТС] #5
Ma3a,Спасибо ,с функций int main(), всё работает ,но вот только я пишу в windows forms , а он опять ругается

Ошибка 1 error C2276: &: недопустимая операция с выражением привязанной функции-члена
Ошибка 2 error C3350: System::Net:: DownloadDataCompletedEventHandler: для конструктора делегата требуется 2 аргументов
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
#pragma endregion
void download_completed(System::Object ^ sender, DownloadDataCompletedEventArgs ^ e)
    {
    cli::array<System::Byte> ^ res = e->Result;
    System::Console::WriteLine(res->Length);
    }
 
private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) 
         {
           
           System::Net::WebClient ^ client = gcnew System::Net::WebClient();
           client->DownloadDataCompleted += gcnew DownloadDataCompletedEventHandler(&download_completed);
           client->DownloadDataAsync(gcnew System::Uri("http://www.cyberforum.ru/images/cyberforum_logo.jpg"));
           System::Console::ReadLine();
         }
0
Ma3a
Эксперт С++
619 / 463 / 31
Регистрация: 28.01.2011
Сообщений: 605
13.08.2011, 18:07 #6
Vitall, в вашем случае делегату DownloadDataCompletedEventHandler, как пишет компилятор, нужно 2 параметра: первым должен идти handle вашей формы, а вторым параметром указатель на член-функцию-обработчик, то есть может выглядеть примерно так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
ref struct form : Form
    {
    form()
        {
        WebClient ^ client = gcnew WebClient();
        client->DownloadDataCompleted += gcnew DownloadDataCompletedEventHandler(this, &form::mymethod);
        }
    void mymethod(Object ^ o, DownloadDataCompletedEventArgs ^ e)
        {
        // ...
        }
    };
1
Vitall
750 / 530 / 23
Регистрация: 03.07.2011
Сообщений: 1,020
13.08.2011, 19:19  [ТС] #7
Ma3a,Спасибо еще раз .Сделал так: void mymethod зарегистрировал как функцию член моей формы ,и проканало .Ну то что вы мне и показали только со структурой !

Добавлено через 31 минуту
Опа сюрприз ,оказывается эта функция не блокирует вызывающий поток ,а я это понял как не блокирует работы программы ,пока загружаются файлы А как сделать что бы программы не блокировалась при загрузке файлов?
0
Ma3a
Эксперт С++
619 / 463 / 31
Регистрация: 28.01.2011
Сообщений: 605
13.08.2011, 19:55 #8
Vitall, как вариант, пустить процесс асинхронного приёма данных в отдельном потоке, чтобы основной поток не морозился. Для этого может подойти например класс System::ComponentModel::BackgroundWorker, пример использования:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using namespace System;
using namespace System::ComponentModel;
using namespace System::Net;
using namespace System::Windows::Forms;
 
ref struct form : Form
    {
    Button ^ bt;
 
    form()
        {
        bt = gcnew Button();
        bt->Click += gcnew EventHandler(this, &form::buttonclick);
        Controls->Add(bt);
        }
 
    void buttonclick(Object ^ o, EventArgs ^ e)
        {
        BackgroundWorker ^ worker = gcnew BackgroundWorker();
        worker->DoWork += gcnew DoWorkEventHandler(this, &form::worker_routine);
        worker->RunWorkerAsync();
        }
 
    void worker_routine(Object ^ o, DoWorkEventArgs ^ e)
        {
        WebClient ^ client = gcnew WebClient();
        client->DownloadDataCompleted += gcnew DownloadDataCompletedEventHandler(this, &form::download_completed);
        client->DownloadDataAsync(gcnew Uri("http://www.cyberforum.ru/"));
        }
 
    void download_completed(Object ^ sender, DownloadDataCompletedEventArgs ^ e)
        {
        cli::array<System::Byte> ^ res = e->Result;
        MessageBox::Show(res->Length + " bytes received");
        }
    };
Добавлено через 9 минут
Также, в принципе можно обойтись и обычным System::Threading::Thread с установленным флагом IsBackground в true, но мне с делегатами заморачиваться как-то не хочется
1
Vitall
750 / 530 / 23
Регистрация: 03.07.2011
Сообщений: 1,020
13.08.2011, 20:18  [ТС] #9
Ma3a ,Спасибо ,теперь все круто
0
13.08.2011, 20:18
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.08.2011, 20:18
Привет! Вот еще темы с ответами:

.NET 4.x Функция System - .NET
Подскажите пожалуйста аналог сишной функции System в .NET 4.0 Заранее спасибо Если вдруг встречали исходный код этой функции, то...

Не находит System - C++/CLI
Среда Visual C++ 2005 Когда пишу using System;Компилятор отвечает error C2873: 'System' : symbol cannot be used in...

System::Net:: - C++/CLI
Пытаюсь узнать свой ip-адрес Пробовал так: System::Net ^ip = gcnew System::Net; url_no-&gt;Text = ip-&gt;IPAddress-&gt;ToString; Но...

Автоматическая вставка URL с обрезанием длинных ссылок - .NET
Есть текст с длинной ссылкой вроде http://msdn.microsoft.com/webservices/default.aspx?pull=/library/en-us/dnmitta/html/tvmwp.asp ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru