【问题标题】:Returning / setting a value within a thread在线程中返回/设置一个值
【发布时间】:2015-11-09 15:36:29
【问题描述】:

我正在尝试在 C# 中打开 OpenFileDialog(代码隐藏,在 asp.net 页面上)。因为常规引用和 system.windows.form 有一些冲突,所以我不得不在线程中使用 OpenFileDialog 框,如下所示:

protected void Button1_Click(object sender, EventArgs e)
{
    Thread newThread = new Thread(new ThreadStart(BrowseForFile));
    newThread.SetApartmentState(ApartmentState.STA);
    newThread.Start();     
}

static void BrowseForFile()
{
    System.Windows.Forms.OpenFileDialog MyFile = new System.Windows.Forms.OpenFileDialog();
    if (MyFile.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {

    }
}

页面的工作方式意味着这必须在 C# 中 - 使用 asp.net 的文件上传将不起作用。

现在,OpenFileDialog 看起来很好,我可以从中获取值,但理想情况下,我需要将值传递到线程(BrowseForFile)并让它与页面上的其他控件一起工作,以便进行设置。但是,我对使用线程非常陌生。

有人可以告诉我,基本上,如何从 Button1_Click 获取整数到 BrowseForFile,以及如何从 BrowseForFile 在页面上设置标签?

【问题讨论】:

  • 您无法在服务器上显示 UI。您需要使用 HTML。
  • 为什么这个标签是 asp.net?对我来说看起来像 windows 窗体?
  • 这可能出现在进行开发时工作,因为您的服务器是您正在开发的同一台计算机,localhost,但在 ASP.NET 应用程序中使用 System.Windows.Forms 是几乎总是错的。

标签: c# asp.net multithreading


【解决方案1】:

如果您使用现代版本的 .net,您可以为此使用 async-await。这使您可以更轻松地与对话框进行通信并将数据传递给执行后台工作的线程。

为了能够使用异步等待:

  • 声明你的函数异步
  • 让您的函数返回 Task 而不是 void 和 Task<TResult> 而不是 TResult。
    • 有一个例外:事件处理程序可能返回 void
    • 在您的异步函数中使用 Task.Run 启动您的其他线程
    • 在其他线程运行时,您可以做其他事情
    • 如果您需要结果:调用 await Task。

在您的情况下,您必须将线程类更改为包含线程类中代码的过程。这个过程可以在任何类别中。它必须声明为 async 并返回 Task 而不是 void:

当然,您必须将线程类更改为异步过程:

private async Task MyThreadProcedureAsync(string fileName)
{
    // do something really slow with fileName and return void
}



protected async void Button1_Click(object sender, EventArgs e)
{
    string fileName = this.BrowseForFile();
    if (!String.IsNullOrEmpty(fileName))
    {
        var myTask = Task.Run( () => MyThreadProcedureAsync(fileName))
        // if desired do other things.
        // before returning make sure the task is ready:
        await myTask;
        // during this wait the UI keeps responsive
    }
}

private string BrowseForFileName()
{
    using (var dlg = new System.Windows.Forms.OpenFileDialog())
    {
        // if needed set some properties; show the dialog:
        var dlgResult = dlg.ShowDialog(this);
        if (dlgResult == System.Windows.Forms.DialogResult.OK)
        {
            return dlg.FileName;
        }
        else
        {
            return null;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 2013-03-31
    • 2013-03-01
    相关资源
    最近更新 更多