Функция C # 2.0 не работает при вызове в отдельном потоке - PullRequest
1 голос
/ 13 октября 2010

У меня есть функция для загрузки почтового сообщения в виде файла MSG с сервера DocuShare.Функция отлично работает при вызове из основного потока.Однако, когда я вызываю функцию в отдельном потоке, загрузка завершается неудачно.Когда я вхожу в код, я вижу, что функция вызывается, все параметры оцениваются правильно, и возвращаемое значение - это то, что я ожидаю.К сожалению, я вижу, файлы не загружаются.

Коды:

    private void btnDownloadMails_Click(object sender, EventArgs e)
    {

        //Thread t = new Thread(new ThreadStart(DownloadMailAsMsg));
        //t.Start(); //Does not work

        DownloadMailAsMsg(); // Works fine           
    }

    void DownloadMailAsMsg()
    {

        DSServerMap.Server dsserver = new DSServerMap.Server();
        if (!SelectMappedServer(ref dsserver, textServer.Text.ToString()))
            return;

        long status = 0;            
        dsserver.DocuShareAddress = textServer.Text;
        dsserver.UserName = textUser.Text;
        dsserver.Password = textPwd.Text;
        status = dsserver.Logon();

        if (status == 0)
        {
            IItemObj objParentItem;
            string[] emailHan = { "MailMessage-12", "MailMessage-13", "MailMessage-31" };
            foreach (string handnum in emailHan)
            {
                objParentItem = (IItemObj)dsserver.CreateObject(handnum);
                DSGATEWAYLib.IGatewayHandler gateway = (DSGATEWAYLib.IGatewayHandler)dsserver.Open();

                objParentItem.AttachGateway(gateway, true);
                objParentItem.Name = @"D:\em\m_" + handnum + ".msg";                    
                int flag = objParentItem.DSDownload(0);
            }
        }
    }

Есть идеи?

Спасибо, Пракаш

Ответы [ 4 ]

4 голосов
/ 13 октября 2010

Может быть, вам нужен поток STA для этого.Однажды у меня была похожая проблема, и следующее решило мою проблему:

Thread t = new Thread((ThreadStart)delegate
                        {   // MAPI does only work in STA threads. Therefore an STA thread needs to be created explicitly for the SendMail call.
                            //...do work here
                        });
t.SetApartmentState(ApartmentState.STA);
t.Start();

Возможно, это решит и вашу проблему.

1 голос
/ 13 октября 2010

Вы пытаетесь получить доступ к свойствам элемента управления в потоках не из пользовательского интерфейса,

например в строках,

    dsserver.DocuShareAddress = textServer.Text; 
    dsserver.UserName = textUser.Text; 
    dsserver.Password = textPwd.Text; 

вы пытаетесь получить доступ к свойствам текста элемента управления пользовательского интерфейса в другом потоке, что фактически вызывает исключение.

Каждое из значений элемента управления, к которому вы хотите получить доступ в разных потоках, вы должны заключить в некоторые аргументы и передать его в поток.

class MyServerParameters{
   string Server;
   string Username;
   string Password;
}


private void btnDownloadMails_Click(object sender, EventArgs e)      
{      

    MyServerParameters p = new MyServerParameters();
    // we are still in UI thread so copy your values
    // to p
    p.Server = textServer.Text;         
    p.Username = textUser.Text;         
    p.Password = textPwd.Text;        
    Thread t = new Thread(new ParametricThreadStart(DownloadMailAsMsg));    
    // pass p to another thread  
    t.Start(p); // this will work...

}  


void DownloadMailAsMsg(object mp)   
{
     // access p back like this...   
     MyServerParameters p = mp as MyServerParameters;


    dsserver.DocuShareAddress = p.Server;    
    dsserver.UserName = p.Username;    
    dsserver.Password = p.Password;   
0 голосов
/ 13 октября 2010

Создать копию .Text свойств элементов управления и ссылаться только на них во втором потоке.

Вы заблокируете свое приложение или получите исключение, если используете другой поток для доступа к любому из элементов управления.

Другой способ - использовать .Invoke(), но в вашем случае вы действительномне не нужно идти туда.

0 голосов
/ 13 октября 2010

Ваш поток должен быть членом класса, а не переменной метода.

Когда ваш метод завершает работу, переменная потока выходит из области видимости и может быть очищена без завершения.

...