我有一个从DocuShare服务器下载mailmessage作为MSG文件的功能。从主线程调用时,该函数可以正常工作。但是,当我在一个单独的线程中调用该函数时,下载失败。当我介入代码时,我可以看到函数被调用,所有参数都被正确计算,返回值是我所期望的。不幸的是,我看到,没有文件被下载。
代码:
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);
}
}
}
有什么想法吗?
由于 普拉卡什
答案 0 :(得分:4)
也许你需要一个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 :(得分:1)
您正尝试在非UI线程中访问Control的属性
例如在行中,
dsserver.DocuShareAddress = textServer.Text;
dsserver.UserName = textUser.Text;
dsserver.Password = textPwd.Text;
您正尝试在不同的线程中访问UI Control的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;
答案 2 :(得分:0)
您的主题应该是类成员而不是方法变量。
当您的方法完成时,线程变量超出范围并且可以在不完成的情况下进行清理。
答案 3 :(得分:0)
创建控件的.Text
属性的副本,并在第二个线程中仅引用它们。
如果您使用不同的线程访问任何控件,您将锁定您的应用程序或获取异常。
其他方式是使用.Invoke()
,但在你的情况下,你真的不需要去那里。